def as_dtype(nbtype): """ Return a numpy dtype instance corresponding to the given Numba type. NotImplementedError is if no correspondence is known. """ nbtype = types.unliteral(nbtype) if isinstance(nbtype, (types.Complex, types.Integer, types.Float)): return np.dtype(str(nbtype)) if nbtype is types.bool_: return np.dtype('?') if isinstance(nbtype, (types.NPDatetime, types.NPTimedelta)): letter = _as_dtype_letters[type(nbtype)] if nbtype.unit: return np.dtype('%s[%s]' % (letter, nbtype.unit)) else: return np.dtype(letter) if isinstance(nbtype, (types.CharSeq, types.UnicodeCharSeq)): letter = _as_dtype_letters[type(nbtype)] return np.dtype('%s%d' % (letter, nbtype.count)) if isinstance(nbtype, types.Record): return as_struct_dtype(nbtype) if isinstance(nbtype, types.EnumMember): return as_dtype(nbtype.dtype) if isinstance(nbtype, types.npytypes.DType): return as_dtype(nbtype.dtype) if isinstance(nbtype, types.NumberClass): return as_dtype(nbtype.dtype) if isinstance(nbtype, types.NestedArray): spec = (as_dtype(nbtype.dtype), tuple(nbtype.shape)) return np.dtype(spec) if isinstance(nbtype, types.PyObject): return np.dtype(object) raise NotImplementedError("%r cannot be represented as a Numpy dtype" % (nbtype, ))
def _prepare_argument(ctxt, bld, inp, tyinp, where='input operand'): """returns an instance of the appropriate Helper (either _ScalarHelper or _ArrayHelper) class to handle the argument. using the polymorphic interface of the Helper classes, scalar and array cases can be handled with the same code""" # first un-Optional Optionals if isinstance(tyinp, types.Optional): oty = tyinp tyinp = tyinp.type inp = ctxt.cast(bld, inp, oty, tyinp) # then prepare the arg for a concrete instance if isinstance(tyinp, types.ArrayCompatible): ary = ctxt.make_array(tyinp)(ctxt, bld, inp) shape = cgutils.unpack_tuple(bld, ary.shape, tyinp.ndim) strides = cgutils.unpack_tuple(bld, ary.strides, tyinp.ndim) return _ArrayHelper(ctxt, bld, shape, strides, ary.data, tyinp.layout, tyinp.dtype, tyinp.ndim, inp) elif (types.unliteral(tyinp) in types.number_domain | {types.boolean} or isinstance(tyinp, types.scalars._NPDatetimeBase)): return _ScalarHelper(ctxt, bld, inp, tyinp) else: raise NotImplementedError('unsupported type for {0}: {1}'.format( where, str(tyinp)))
def generic(self, args, kws): assert not kws if len(args) == 1: # One-argument type() -> return the __class__ # Avoid literal types arg = types.unliteral(args[0]) classty = self.context.resolve_getattr(arg, "__class__") if classty is not None: return signature(classty, *args)
def unify_pairs(self, first, second): """ Try to unify the two given types. A third type is returned, or None in case of failure. """ if first == second: return first if first is types.undefined: return second elif second is types.undefined: return first # Types with special unification rules unified = first.unify(self, second) if unified is not None: return unified unified = second.unify(self, first) if unified is not None: return unified # Other types with simple conversion rules conv = self.can_convert(fromty=first, toty=second) if conv is not None and conv <= Conversion.safe: # Can convert from first to second return second conv = self.can_convert(fromty=second, toty=first) if conv is not None and conv <= Conversion.safe: # Can convert from second to first return first if isinstance(first, types.Literal) or \ isinstance(second, types.Literal): first = types.unliteral(first) second = types.unliteral(second) return self.unify_pairs(first, second) # Cannot unify return None
def _resolve_builtin_function_type(self, func, args, kws): # NOTE: we should reduce usage of this if func in self._functions: # Note: Duplicating code with types.Function.get_call_type(). # *defns* are CallTemplates. defns = self._functions[func] for defn in defns: for support_literals in [True, False]: if support_literals: res = defn.apply(args, kws) else: fixedargs = [types.unliteral(a) for a in args] res = defn.apply(fixedargs, kws) if res is not None: return res
def _do_work_getattr(self, state, work_list, block, i, expr): recv_type = state.type_annotation.typemap[expr.value.name] recv_type = types.unliteral(recv_type) matched = state.typingctx.find_matching_getattr_template( recv_type, expr.attr, ) if not matched: return False template = matched['template'] if getattr(template, 'is_method', False): # The attribute template is representing a method. # Don't inline the getattr. return False inline_type = getattr(template, '_inline', None) if inline_type is None: # inline not defined return False sig = typing.signature(matched['return_type'], recv_type) arg_typs = sig.args if not inline_type.is_never_inline: try: impl = template._overload_func(recv_type) if impl is None: raise Exception # abort for this template except Exception: return False else: return False is_method = False return self._run_inliner( state, inline_type, sig, template, arg_typs, expr, i, impl, block, work_list, is_method, )
def generic(self, args, kws): assert not kws assert len(args) == 1 column = types.unliteral(args[0]) ret_typ = column if (isinstance(column, types.List) and (isinstance(column.dtype, types.Number) or column.dtype == types.boolean)): ret_typ = types.Array(column.dtype, 1, 'C') if (isinstance(column, types.List) and (column.dtype == string_type or isinstance(column.dtype, types.Optional) and column.dtype.type == string_type)): ret_typ = string_array_type if isinstance(column, SeriesType): ret_typ = column.data # TODO: add other types return signature(ret_typ, column)
def _get_attr_info(self, state, expr): recv_type = state.type_annotation.typemap[expr.value.name] recv_type = types.unliteral(recv_type) matched = state.typingctx.find_matching_getattr_template( recv_type, expr.attr, ) if not matched: return None template = matched['template'] if getattr(template, 'is_method', False): # The attribute template is representing a method. # Don't inline the getattr. return None templates = [template] sig = typing.signature(matched['return_type'], recv_type) arg_typs = sig.args is_method = False return templates, sig, arg_typs, is_method
def resolve_getattr(self, typ, attr): """ Resolve getting the attribute *attr* (a string) on the Numba type. The attribute's type is returned, or None if resolution failed. """ def core(typ): out = self.find_matching_getattr_template(typ, attr) if out: return out['return_type'] out = core(typ) if out is not None: return out # Try again without literals out = core(types.unliteral(typ)) if out is not None: return out if isinstance(typ, types.Module): attrty = self.resolve_module_constants(typ, attr) if attrty is not None: return attrty
def __unliteral__(self): return signature(types.unliteral(self.return_type), *map(types.unliteral, self.args))
def unliteral_all(args): return tuple(types.unliteral(a) for a in args)
def resolve_split(self, dict, args, kws): assert not kws assert len(args) == 1 return signature(types.List(std_str_type), types.unliteral(args[0]))
def preprocess_fields(self, fields): # This method is called by the type constructor for additional # preprocessing on the fields. # Here, we don't want the struct to take Literal types. return tuple((name, types.unliteral(typ)) for name, typ in fields)
def preprocess_fields(self, fields): return tuple((name, types.unliteral(typ)) for name, typ in fields)