def generic_resolve(self, instance, attr): if attr in instance.struct: return instance.struct[attr] elif attr in instance.jitmethods: meth = instance.jitmethods[attr] class MethodTemplate(templates.AbstractTemplate): key = (instance, attr) def generic(self, args, kws): args = (instance, ) + tuple(args) template, args, kws = meth.get_call_template(args, kws) sig = template(self.context).apply(args, kws) sig = templates.signature(sig.return_type, *sig.args[1:], recvr=sig.args[0]) return sig return types.BoundFunction(MethodTemplate, instance) elif attr in instance.jitprops: impdct = instance.jitprops[attr] getter = impdct['get'] template, args, kws = getter.get_call_template([instance], {}) sig = template(self.context).apply(args, kws) return sig.return_type
def generic_resolve(self, instance, attr): if attr in instance.struct: # It's a struct field => the type is well-known return instance.struct[attr] elif attr in instance.jitmethods: # It's a jitted method => typeinfer it meth = instance.jitmethods[attr] disp_type = types.Dispatcher(meth) class MethodTemplate(templates.AbstractTemplate): key = (self.key, attr) def generic(self, args, kws): args = (instance, ) + tuple(args) sig = disp_type.get_call_type(self.context, args, kws) return sig.as_method() return types.BoundFunction(MethodTemplate, instance) elif attr in instance.jitprops: # It's a jitted property => typeinfer its getter impdct = instance.jitprops[attr] getter = impdct['get'] disp_type = types.Dispatcher(getter) sig = disp_type.get_call_type(self.context, (instance, ), {}) return sig.return_type
def test_equality(self): self.assertEqual(types.int32, types.int32) self.assertEqual(types.uint32, types.uint32) self.assertEqual(types.complex64, types.complex64) self.assertEqual(types.float32, types.float32) # Different signedness self.assertNotEqual(types.int32, types.uint32) # Different width self.assertNotEqual(types.int64, types.int32) self.assertNotEqual(types.float64, types.float32) self.assertNotEqual(types.complex64, types.complex128) # Different domain self.assertNotEqual(types.int64, types.float64) self.assertNotEqual(types.uint64, types.float64) self.assertNotEqual(types.complex64, types.float64) # Same arguments but different return types get_pointer = None sig_a = typing.signature(types.intp, types.intp) sig_b = typing.signature(types.voidptr, types.intp) a = types.ExternalFunctionPointer(sig=sig_a, get_pointer=get_pointer) b = types.ExternalFunctionPointer(sig=sig_b, get_pointer=get_pointer) self.assertNotEqual(a, b) # Different call convention a = types.ExternalFunctionPointer(sig=sig_a, get_pointer=get_pointer) b = types.ExternalFunctionPointer(sig=sig_a, get_pointer=get_pointer, cconv='stdcall') self.assertNotEqual(a, b) # Different get_pointer a = types.ExternalFunctionPointer(sig=sig_a, get_pointer=get_pointer) b = types.ExternalFunctionPointer(sig=sig_a, get_pointer=object()) self.assertNotEqual(a, b) # Different template classes bearing the same name class DummyTemplate(object): key = "foo" a = types.BoundFunction(DummyTemplate, types.int32) class DummyTemplate(object): key = "bar" b = types.BoundFunction(DummyTemplate, types.int32) self.assertNotEqual(a, b) # Different dtypes self.assertNotEqual(types.DType(types.int32), types.DType(types.int64))
def generic_resolve(self, rolling, func_name): if func_name not in supported_rolling_funcs: raise ValueError("only ({}) supported in rolling".format( ", ".join(supported_rolling_funcs))) template_key = 'rolling.' + func_name # output is always float64 out_arr = types.Array(types.float64, 1, 'C') # TODO: handle Series case (explicit select) columns = rolling.selection # handle 'on' case if rolling.on is not None: columns = columns + (rolling.on, ) # Pandas sorts the output column names _flex_binary_moment # line: res_columns = arg1.columns.union(arg2.columns) columns = tuple(sorted(columns)) n_out_cols = len(columns) out_data = [out_arr] * n_out_cols if rolling.on is not None: # offset key's data type is preserved out_ind = columns.index(rolling.on) in_ind = rolling.df_type.columns.index(rolling.on) out_data[out_ind] = rolling.df_type.data[in_ind] out_typ = DataFrameType(tuple(out_data), None, columns) class MethodTemplate(AbstractTemplate): key = template_key def generic(self, args, kws): if func_name in ('cov', 'corr'): if len(args) != 1: raise ValueError( "rolling {} requires one argument (other)".format( func_name)) # XXX pandas only accepts variable window cov/corr # when both inputs have time index if rolling.on is not None: raise ValueError( "variable window rolling {} not supported yet.". format(func_name)) # TODO: support variable window rolling cov/corr which is only # possible in pandas with time index other = args[0] # df on df cov/corr returns common columns only (without # pairwise flag) # TODO: support pairwise arg out_cols = tuple(sorted(set(columns) | set(other.columns))) return signature( DataFrameType((out_arr, ) * len(out_cols), None, out_cols), *args) return signature(out_typ, *args) return types.BoundFunction(MethodTemplate, rolling)
def generic_resolve(self, s_str, func_name): if func_name not in str2str_methods: raise ValueError( "Series.str.{} is not supported yet".format(func_name)) template_key = 'strmethod.' + func_name out_typ = SeriesType(string_type) class MethodTemplate(AbstractTemplate): key = template_key def generic(self, args, kws): return signature(out_typ, *args) return types.BoundFunction(MethodTemplate, s_str)
def generic_resolve(self, s_str, func_name): if sdc.config.config_pipeline_hpat_default and func_name in str2str_methods: template_key = 'strmethod.' + func_name out_typ = SeriesType(string_type) class MethodTemplate(AbstractTemplate): key = template_key def generic(self, args, kws): return signature(out_typ, *args) return types.BoundFunction(MethodTemplate, s_str) if func_name in str2str_methods_excluded: return raise NotImplementedError('Series.str.{} is not supported yet'.format(func_name))
def resolve(self, typeinfer, typevars, fnty): assert fnty context = typeinfer.context n_pos_args = len(self.args) kwds = [kw for (kw, var) in self.kws] argtypes = [typevars[a.name] for a in self.args] argtypes += [typevars[var.name] for (kw, var) in self.kws] if self.vararg is not None: argtypes.append(typevars[self.vararg.name]) if not all(a.defined for a in argtypes): # Cannot resolve call type until all argument types are known return args = tuple(a.getone() for a in argtypes) pos_args = args[:n_pos_args] if self.vararg is not None: if not isinstance(args[-1], types.BaseTuple): # Unsuitable for *args # (Python is more lenient and accepts all iterables) return pos_args += args[-1].types args = args[:-1] kw_args = dict(zip(kwds, args[n_pos_args:])) sig = context.resolve_function_type(fnty, pos_args, kw_args) if sig is None: desc = context.explain_function_type(fnty) headtemp = "Invalid usage of {0} with parameters ({1})" head = headtemp.format(fnty, ', '.join(map(str, args))) msg = '\n'.join([head, desc]) raise TypingError(msg, loc=self.loc) typeinfer.add_type(self.target, sig.return_type) # If the function is a bound function and its receiver type # was refined, propagate it. if (isinstance(fnty, types.BoundFunction) and sig.recvr is not None and sig.recvr != fnty.this): refined_this = context.unify_pairs(sig.recvr, fnty.this) if refined_this.is_precise(): refined_fnty = types.BoundFunction(fnty.template, this=refined_this) typeinfer.propagate_refined_type(self.func, refined_fnty) self.signature = sig
def array_attribute_attachment(self, ary): return types.BoundFunction(temp_class, ary)
def resolve_from_buffer(self, ffi): return types.BoundFunction(FFI_from_buffer, types.ffi)
def resolve_prod(self, ary): return types.BoundFunction(Array_prod, ary)
def resolve_sum(self, ary): return types.BoundFunction(Array_sum, ary)