2727 is_integer_dtype , is_categorical_dtype ,
2828 is_object_dtype , is_timedelta64_dtype ,
2929 is_datetime64_dtype , is_datetime64tz_dtype ,
30- is_bool_dtype ,
30+ is_bool_dtype , is_extension_array_dtype ,
3131 is_list_like ,
3232 is_scalar ,
3333 _ensure_object )
@@ -1003,8 +1003,18 @@ def _arith_method_SERIES(cls, op, special):
10031003 if op is divmod else _construct_result )
10041004
10051005 def na_op (x , y ):
1006- import pandas .core .computation .expressions as expressions
1006+ # handle extension array ops
1007+ # TODO(extension)
1008+ # the ops *between* non-same-type extension arrays are not
1009+ # very well defined
1010+ if (is_extension_array_dtype (x ) or is_extension_array_dtype (y )):
1011+ if (op_name .startswith ('__r' ) and not
1012+ is_extension_array_dtype (y ) and not
1013+ is_scalar (y )):
1014+ y = x .__class__ ._from_sequence (y )
1015+ return op (x , y )
10071016
1017+ import pandas .core .computation .expressions as expressions
10081018 try :
10091019 result = expressions .evaluate (op , str_rep , x , y , ** eval_kwargs )
10101020 except TypeError :
@@ -1025,6 +1035,7 @@ def na_op(x, y):
10251035 return result
10261036
10271037 def safe_na_op (lvalues , rvalues ):
1038+ # all others
10281039 try :
10291040 with np .errstate (all = 'ignore' ):
10301041 return na_op (lvalues , rvalues )
@@ -1035,14 +1046,21 @@ def safe_na_op(lvalues, rvalues):
10351046 raise
10361047
10371048 def wrapper (left , right ):
1038-
10391049 if isinstance (right , ABCDataFrame ):
10401050 return NotImplemented
10411051
10421052 left , right = _align_method_SERIES (left , right )
10431053 res_name = get_op_result_name (left , right )
10441054
1045- if is_datetime64_dtype (left ) or is_datetime64tz_dtype (left ):
1055+ if is_categorical_dtype (left ):
1056+ raise TypeError ("{typ} cannot perform the operation "
1057+ "{op}" .format (typ = type (left ).__name__ , op = str_rep ))
1058+
1059+ elif (is_extension_array_dtype (left ) or
1060+ is_extension_array_dtype (right )):
1061+ pass
1062+
1063+ elif is_datetime64_dtype (left ) or is_datetime64tz_dtype (left ):
10461064 result = dispatch_to_index_op (op , left , right , pd .DatetimeIndex )
10471065 return construct_result (left , result ,
10481066 index = left .index , name = res_name ,
@@ -1054,10 +1072,6 @@ def wrapper(left, right):
10541072 index = left .index , name = res_name ,
10551073 dtype = result .dtype )
10561074
1057- elif is_categorical_dtype (left ):
1058- raise TypeError ("{typ} cannot perform the operation "
1059- "{op}" .format (typ = type (left ).__name__ , op = str_rep ))
1060-
10611075 lvalues = left .values
10621076 rvalues = right
10631077 if isinstance (rvalues , ABCSeries ):
@@ -1136,6 +1150,14 @@ def na_op(x, y):
11361150 # The `not is_scalar(y)` check excludes the string "category"
11371151 return op (y , x )
11381152
1153+ # handle extension array ops
1154+ # TODO(extension)
1155+ # the ops *between* non-same-type extension arrays are not
1156+ # very well defined
1157+ elif (is_extension_array_dtype (x ) or
1158+ is_extension_array_dtype (y )):
1159+ return op (x , y )
1160+
11391161 elif is_object_dtype (x .dtype ):
11401162 result = _comp_method_OBJECT_ARRAY (op , x , y )
11411163
0 commit comments