@@ -48,30 +48,26 @@ class AmbiguousIndexError(PandasError, KeyError):
48
48
_INT64_DTYPE = np .dtype (np .int64 )
49
49
_DATELIKE_DTYPES = set ([np .dtype (t ) for t in ['M8[ns]' , 'm8[ns]' ]])
50
50
51
-
52
- def is_series (obj ):
53
- return getattr (obj , '_typ' , None ) == 'series'
54
-
55
-
56
- def is_sparse_series (obj ):
57
- return getattr (obj , '_subtyp' , None ) in ('sparse_series' , 'sparse_time_series' )
58
-
59
-
60
- def is_sparse_array_like (obj ):
61
- return getattr (obj , '_subtyp' , None ) in ['sparse_array' , 'sparse_series' , 'sparse_array' ]
62
-
63
-
64
- def is_dataframe (obj ):
65
- return getattr (obj , '_typ' , None ) == 'dataframe'
66
-
67
-
68
- def is_panel (obj ):
69
- return getattr (obj , '_typ' , None ) == 'panel'
70
-
71
-
72
- def is_generic (obj ):
73
- return getattr (obj , '_data' , None ) is not None
74
-
51
+ # define abstract base classes to enable isinstance type checking on our objects
52
+ def create_pandas_abc_type (name , attr , comp ):
53
+ @classmethod
54
+ def _check (cls , inst ):
55
+ return getattr (inst , attr , None ) in comp
56
+ dct = dict (__instancecheck__ = _check ,
57
+ __subclasscheck__ = _check )
58
+ meta = type ("ABCBase" , (type ,), dct )
59
+ return meta (name , tuple (), dct )
60
+
61
+ ABCSeries = create_pandas_abc_type ("ABCSeries" , "_typ" , ("series" ,))
62
+ ABCDataFrame = create_pandas_abc_type ("ABCDataFrame" , "_typ" , ("dataframe" ,))
63
+ ABCPanel = create_pandas_abc_type ("ABCPanel" , "_typ" , ("panel" ,))
64
+ ABCSparseSeries = create_pandas_abc_type ("ABCSparseSeries" , "_subtyp" , ('sparse_series' , 'sparse_time_series' ))
65
+ ABCSparseArray = create_pandas_abc_type ("ABCSparseArray" , "_subtyp" , ('sparse_array' , 'sparse_series' ))
66
+
67
+ class _ABCGeneric (type ):
68
+ def __instancecheck__ (cls , inst ):
69
+ return hasattr (inst , "_data" )
70
+ ABCGeneric = _ABCGeneric ("ABCGeneric" , tuple (), {})
75
71
76
72
def isnull (obj ):
77
73
"""Detect missing values (NaN in numeric arrays, None/NaN in object arrays)
@@ -94,9 +90,9 @@ def _isnull_new(obj):
94
90
if lib .isscalar (obj ):
95
91
return lib .checknull (obj )
96
92
97
- if is_series (obj ) or isinstance ( obj , np .ndarray ):
93
+ if isinstance (obj , ( ABCSeries , np .ndarray ) ):
98
94
return _isnull_ndarraylike (obj )
99
- elif is_generic (obj ):
95
+ elif isinstance (obj , ABCGeneric ):
100
96
return obj .apply (isnull )
101
97
elif isinstance (obj , list ) or hasattr (obj , '__array__' ):
102
98
return _isnull_ndarraylike (np .asarray (obj ))
@@ -119,9 +115,9 @@ def _isnull_old(obj):
119
115
if lib .isscalar (obj ):
120
116
return lib .checknull_old (obj )
121
117
122
- if is_series (obj ) or isinstance ( obj , np .ndarray ):
118
+ if isinstance (obj , ( ABCSeries , np .ndarray ) ):
123
119
return _isnull_ndarraylike_old (obj )
124
- elif is_generic (obj ):
120
+ elif isinstance (obj , ABCGeneric ):
125
121
return obj .apply (_isnull_old )
126
122
elif isinstance (obj , list ) or hasattr (obj , '__array__' ):
127
123
return _isnull_ndarraylike_old (np .asarray (obj ))
@@ -182,7 +178,7 @@ def _isnull_ndarraylike(obj):
182
178
else :
183
179
result = np .isnan (obj )
184
180
185
- if is_series (obj ):
181
+ if isinstance (obj , ABCSeries ):
186
182
from pandas import Series
187
183
result = Series (result , index = obj .index , copy = False )
188
184
@@ -213,7 +209,7 @@ def _isnull_ndarraylike_old(obj):
213
209
else :
214
210
result = - np .isfinite (obj )
215
211
216
- if is_series (obj ):
212
+ if isinstance (obj , ABCSeries ):
217
213
from pandas import Series
218
214
result = Series (result , index = obj .index , copy = False )
219
215
@@ -1300,7 +1296,7 @@ def convert(td, type):
1300
1296
return np .array ([ convert (v ,dtype ) for v in value ], dtype = 'm8[ns]' )
1301
1297
1302
1298
# deal with numpy not being able to handle certain timedelta operations
1303
- if ( isinstance (value , np .ndarray ) or is_series ( value )) and value .dtype .kind == 'm' :
1299
+ if isinstance (value , ( ABCSeries , np .ndarray )) and value .dtype .kind == 'm' :
1304
1300
if value .dtype != 'timedelta64[ns]' :
1305
1301
value = value .astype ('timedelta64[ns]' )
1306
1302
return value
@@ -1384,7 +1380,7 @@ def _possibly_cast_to_datetime(value, dtype, coerce=False):
1384
1380
1385
1381
1386
1382
def _is_bool_indexer (key ):
1387
- if isinstance (key , np .ndarray ) or is_series ( key ):
1383
+ if isinstance (key , ( ABCSeries , np .ndarray )):
1388
1384
if key .dtype == np .object_ :
1389
1385
key = np .asarray (_values_from_object (key ))
1390
1386
0 commit comments