def argsort_overload(a, axis=-1, kind=None, order=None): _func_name = 'argsort' ty_checker = TypeChecker(_func_name) ty_checker.check(a, types.Array) if not is_default(axis, -1): raise TypingError(f'{_func_name} Unsupported parameter axis') if not is_default(order, None): raise TypingError(f'{_func_name} Unsupported parameter order') def argsort_impl(a, axis=-1, kind=None, order=None): _kind = 'quicksort' if kind is not None: _kind = kind if _kind == 'quicksort': return parallel_argsort(a) elif _kind == 'mergesort': return parallel_stable_argsort(a) else: raise ValueError("Unsupported value of 'kind' parameter") return argsort_impl
def pd_multi_index_from_product_overload(cls, iterables, sortorder=None, names=None): if cls.instance_type is not MultiIndexType: return _func_name = f'Method from_product()' valid_levels_data_types = sdc_pandas_index_types + sdc_pandas_df_column_types + ( types.List, types.ListType) ty_checker = TypeChecker(_func_name) if not (isinstance(iterables, (types.List, types.ListType, types.UniTuple)) and isinstance(iterables.dtype, valid_levels_data_types) or isinstance(iterables, types.Tuple) and all( map(lambda x: isinstance(x, valid_levels_data_types), iterables))): ty_checker.raise_exc(iterables, 'list or tuple of tuples ', 'iterables') if not (isinstance(sortorder, (types.Omitted, types.NoneType)) or sortorder is None): raise TypingError( '{} Unsupported parameters. Given sortorder: {}'.format( _func_name, sortorder)) if not (isinstance(names, (types.Omitted, types.NoneType)) or names is None): raise TypingError('{} Unsupported parameters. Given names: {}'.format( _func_name, names)) def pd_multi_index_from_product_impl(cls, iterables, sortorder=None, names=None): # TO-DO: support indexes.unique() method and use it here levels_factorized = sdc_tuple_map(factorize_level, iterables) levels_names = sdc_tuple_map(sdc_indexes_get_name, iterables) index_levels = sdc_tuple_map(lambda x: fix_df_index(list(x[0])), levels_factorized) temp_cumprod_sizes = [ 1, ] codes_info = sdc_tuple_map(next_codes_info, levels_factorized, temp_cumprod_sizes) res_index_size = temp_cumprod_sizes[-1] index_codes = sdc_tuple_map(next_codes_array, codes_info, res_index_size) res = sdc_pandas_multi_index_ctor(index_levels, index_codes, name=levels_names) return res return pd_multi_index_from_product_impl
def _parse_nested_sequence(context, typ): """ Parse a (possibly 0d) nested sequence type. A (ndim, dtype) tuple is returned. Note the sequence may still be heterogeneous, as long as it converts to the given dtype. """ if isinstance(typ, (types.Buffer, )): raise TypingError("%r not allowed in a homogeneous sequence" % typ) elif isinstance(typ, (types.Sequence, )): n, dtype = _parse_nested_sequence(context, typ.dtype) return n + 1, dtype elif isinstance(typ, (types.BaseTuple, )): if typ.count == 0: # Mimick Numpy's behaviour return 1, types.float64 n, dtype = _parse_nested_sequence(context, typ[0]) dtypes = [dtype] for i in range(1, typ.count): _n, dtype = _parse_nested_sequence(context, typ[i]) if _n != n: raise TypingError("type %r does not have a regular shape" % (typ, )) dtypes.append(dtype) dtype = context.unify_types(*dtypes) if dtype is None: raise TypingError("cannot convert %r to a homogeneous type" % typ) return n + 1, dtype else: # Scalar type => check it's valid as a Numpy array dtype as_dtype(typ) return 0, typ
def sdc_pandas_series_operator_binop(self, other): """ Pandas Series operator :attr:`pandas.Series.binop` implementation Note: Currently implemented for numeric Series only. Differs from Pandas in returning Series with fixed dtype :obj:`float64` .. only:: developer **Test**: python -m sdc.runtests -k sdc.tests.test_series.TestSeries.test_series_op1* python -m sdc.runtests -k sdc.tests.test_series.TestSeries.test_series_op2* python -m sdc.runtests -k sdc.tests.test_series.TestSeries.test_series_operator_binop* Parameters ---------- series: :obj:`pandas.Series` Input series other: :obj:`pandas.Series` or :obj:`scalar` Series or scalar value to be used as a second argument of binary operation Returns ------- :obj:`pandas.Series` The result of the operation """ _func_name = 'Method comp_binop().' ty_checker = TypeChecker(_func_name) self_is_series, other_is_series = isinstance(self, SeriesType), isinstance(other, SeriesType) if not (self_is_series or other_is_series): return None # this overload is not for string series self_is_string_series = self_is_series and isinstance(self.dtype, types.UnicodeType) other_is_string_series = other_is_series and isinstance(other.dtype, types.UnicodeType) if self_is_string_series or other_is_string_series: return None if not isinstance(self, (SeriesType, types.Number)): ty_checker.raise_exc(self, 'pandas.series or scalar', 'self') if not isinstance(other, (SeriesType, types.Number)): ty_checker.raise_exc(other, 'pandas.series or scalar', 'other') operands_are_series = self_is_series and other_is_series if operands_are_series: series_indexes_comparable = check_types_comparable(self.index, other.index) if not series_indexes_comparable: raise TypingError('{} Not implemented for series with not-comparable indexes. \ Given: self.index={}, other.index={}'.format(_func_name, self.index, other.index)) series_data_comparable = check_types_comparable(self, other) if not series_data_comparable: raise TypingError('{} Not supported for not-comparable operands. \ Given: self={}, other={}'.format(_func_name, self, other)) def series_operator_binop_wrapper(self, other): return sdc_binop(self, other) return series_operator_binop_wrapper
def _from_meminfo(typingctx, mi, dicttyperef): """Recreate a dictionary from a MemInfoPointer """ if mi != _meminfo_dictptr: raise TypingError('expected a MemInfoPointer for dict.') dicttype = dicttyperef.instance_type if not isinstance(dicttype, DictType): raise TypingError('expected a {}'.format(DictType)) def codegen(context, builder, sig, args): [tmi, tdref] = sig.args td = tdref.instance_type [mi, _] = args ctor = cgutils.create_struct_proxy(td) dstruct = ctor(context, builder) data_pointer = context.nrt.meminfo_data(builder, mi) data_pointer = builder.bitcast(data_pointer, ll_dict_type.as_pointer()) dstruct.data = builder.load(data_pointer) dstruct.meminfo = mi return impl_ret_borrowed( context, builder, dicttype, dstruct._getvalue(), ) sig = dicttype(mi, dicttyperef) return sig, codegen
def sdc_pandas_series_operator_comp_binop(self, other): """ Pandas Series operator :attr:`pandas.Series.comp_binop` implementation .. only:: developer **Test**: python -m sdc.runtests -k sdc.tests.test_series.TestSeries.test_series_op7* python -m sdc.runtests -k sdc.tests.test_series.TestSeries.test_series_operator_comp_binop* Parameters ---------- series: :obj:`pandas.Series` Input series other: :obj:`pandas.Series` or :obj:`scalar` Series or scalar value to be used as a second argument of binary operation Returns ------- :obj:`pandas.Series` The result of the operation """ _func_name = 'Operator comp_binop().' ty_checker = TypeChecker(_func_name) self_is_series, other_is_series = isinstance(self, SeriesType), isinstance( other, SeriesType) if not (self_is_series or other_is_series): return None if not isinstance(self, (SeriesType, types.Number, types.UnicodeType)): ty_checker.raise_exc(self, 'pandas.series or scalar', 'self') if not isinstance(other, (SeriesType, types.Number, types.UnicodeType)): ty_checker.raise_exc(other, 'pandas.series or scalar', 'other') operands_are_series = self_is_series and other_is_series if operands_are_series: none_or_numeric_indexes = ((isinstance(self.index, types.NoneType) or check_index_is_numeric(self)) and (isinstance(other.index, types.NoneType) or check_index_is_numeric(other))) series_indexes_comparable = check_types_comparable( self.index, other.index) or none_or_numeric_indexes if not series_indexes_comparable: raise TypingError( '{} Not implemented for series with not-comparable indexes. \ Given: self.index={}, other.index={}'.format( _func_name, self.index, other.index)) series_data_comparable = check_types_comparable(self, other) if not series_data_comparable: raise TypingError('{} Not supported for not-comparable operands. \ Given: self={}, other={}'.format(_func_name, self, other)) def sdc_pandas_series_operator_comp_binop_impl(self, other): return self.comp_binop(other) return sdc_pandas_series_operator_comp_binop_impl
def assert_heap_type(heap): if not isinstance(heap, (types.List, types.ListType)): raise TypingError('heap argument must be a list') dt = heap.dtype if isinstance(dt, types.Complex): msg = ("'<' not supported between instances " "of 'complex' and 'complex'") raise TypingError(msg)
def check_input_types(n, iterable): if not isinstance(n, (types.Integer, types.Boolean)): raise TypingError("First argument 'n' must be an integer") # heapq also accepts 1.0 (but not 0.0, 2.0, 3.0...) but # this isn't replicated if not isinstance(iterable, (types.Sequence, types.Array, types.ListType)): raise TypingError("Second argument 'iterable' must be iterable")
def _check_linalg_matrix(a, func_name): if not isinstance(a, types.Array): return if not a.ndim == 2: raise TypingError("np.linalg.%s() only supported on 2-D arrays" % func_name) if not isinstance(a.dtype, (types.Float, types.Complex)): raise TypingError("np.linalg.%s() only supported on " "float and complex arrays" % func_name)
def apply(self, args, kws): generic = getattr(self, "generic") typer = generic() match_sig = inspect.signature(typer) try: match_sig.bind(*args, **kws) except TypeError as e: # bind failed, raise, if there's a # ValueError then there's likely unrecoverable # problems raise TypingError(str(e)) from e sig = typer(*args, **kws) # Unpack optional type if no matching signature if sig is None: if any(isinstance(x, types.Optional) for x in args): def unpack_opt(x): if isinstance(x, types.Optional): return x.type else: return x args = list(map(unpack_opt, args)) sig = typer(*args, **kws) if sig is None: return # Get the pysig try: pysig = typer.pysig except AttributeError: pysig = utils.pysignature(typer) # Fold any keyword arguments bound = pysig.bind(*args, **kws) if bound.kwargs: raise TypingError("unsupported call signature") if not isinstance(sig, Signature): # If not a signature, `sig` is assumed to be the return type if not isinstance(sig, types.Type): raise TypeError("invalid return type for callable template: " "got %r" % (sig, )) sig = signature(sig, *bound.args) if self.recvr is not None: sig = sig.replace(recvr=self.recvr) # Hack any omitted parameters out of the typer's pysig, # as lowering expects an exact match between formal signature # and actual args. if len(bound.args) < len(pysig.parameters): parameters = list(pysig.parameters.values())[:len(bound.args)] pysig = pysig.replace(parameters=parameters) sig = sig.replace(pysig=pysig) cases = [sig] return self._select(cases, bound.args, bound.kwargs)
def matmul_typer(self, a, b, out=None): """ Typer function for Numpy matrix multiplication. """ if not isinstance(a, types.Array) or not isinstance(b, types.Array): return if not all(x.ndim in (1, 2) for x in (a, b)): raise TypingError("%s only supported on 1-D and 2-D arrays" % (self.func_name, )) # Output dimensionality ndims = set([a.ndim, b.ndim]) if ndims == set([2]): # M * M out_ndim = 2 elif ndims == set([1, 2]): # M* V and V * M out_ndim = 1 elif ndims == set([1]): # V * V out_ndim = 0 if out is not None: if out_ndim == 0: raise TypeError( "explicit output unsupported for vector * vector") elif out.ndim != out_ndim: raise TypeError("explicit output has incorrect dimensionality") if not isinstance(out, types.Array) or out.layout != "C": raise TypeError("output must be a C-contiguous array") all_args = (a, b, out) else: all_args = (a, b) if not (config.DISABLE_PERFORMANCE_WARNINGS or all(x.layout in "CF" for x in (a, b))): msg = "%s is faster on contiguous arrays, called on %s" % ( self.func_name, (a, b), ) warnings.warn(NumbaPerformanceWarning(msg)) if not all(x.dtype == a.dtype for x in all_args): raise TypingError("%s arguments must all have the same dtype" % (self.func_name, )) if not isinstance(a.dtype, (types.Float, types.Complex)): raise TypingError("%s only supported on float and complex arrays" % (self.func_name, )) if out: return out elif out_ndim > 0: return types.Array(a.dtype, out_ndim, "C") else: return a.dtype
def generic(self, args, kws): ufunc = self.ufunc base_types, explicit_outputs, ndims, layout = self._handle_inputs( ufunc, args, kws) ufunc_loop = ufunc_find_matching_loop(ufunc, base_types) if ufunc_loop is None: raise TypingError("can't resolve ufunc {0} for types {1}".format( ufunc.__name__, args)) # check if all the types involved in the ufunc loop are supported in this mode if not supported_ufunc_loop(ufunc, ufunc_loop): msg = "ufunc '{0}' using the loop '{1}' not supported in this mode" raise TypingError( msg=msg.format(ufunc.__name__, ufunc_loop.ufunc_sig)) # if there is any explicit output type, check that it is valid explicit_outputs_np = [as_dtype(tp.dtype) for tp in explicit_outputs] # Numpy will happily use unsafe conversions (although it will actually warn) if not all( np.can_cast(fromty, toty, 'unsafe') for (fromty, toty ) in zip(ufunc_loop.numpy_outputs, explicit_outputs_np)): msg = "ufunc '{0}' can't cast result to explicit result type" raise TypingError(msg=msg.format(ufunc.__name__)) # A valid loop was found that is compatible. The result of type inference should # be based on the explicit output types, and when not available with the type given # by the selected NumPy loop out = list(explicit_outputs) implicit_output_count = ufunc.nout - len(explicit_outputs) if implicit_output_count > 0: # XXX this is sometimes wrong for datetime64 and timedelta64, # as ufunc_find_matching_loop() doesn't do any type inference ret_tys = ufunc_loop.outputs[-implicit_output_count:] if ndims > 0: assert layout is not None ret_tys = [ types.Array(dtype=ret_ty, ndim=ndims, layout=layout) for ret_ty in ret_tys ] ret_tys = [ resolve_output_type(self.context, args, ret_ty) for ret_ty in ret_tys ] out.extend(ret_tys) # note: although the previous code should support multiple return values, only one # is supported as of now (signature may not support more than one). # there is an check enforcing only one output out.extend(args) return signature(*out)
def impl_extend(l, iterable): if not isinstance(l, types.ListType): return if not isinstance(iterable, types.IterableType): raise TypingError("extend argument must be iterable") _check_for_none_typed(l, "extend") def select_impl(): if isinstance(iterable, types.ListType): def impl(l, iterable): if not l._is_mutable(): raise ValueError("list is immutable") # guard against l.extend(l) if l is iterable: iterable = iterable.copy() for i in iterable: l.append(i) return impl else: def impl(l, iterable): for i in iterable: l.append(i) return impl if l.is_precise(): # Handle the precise case. return select_impl() else: # Handle the imprecise case, try to 'guess' the underlying type of the # values in the iterable. if hasattr(iterable, "dtype"): # tuples and arrays ty = iterable.dtype elif hasattr(iterable, "item_type"): # lists ty = iterable.item_type elif hasattr(iterable, "yield_type"): # iterators and generators ty = iterable.yield_type elif isinstance(iterable, types.UnicodeType): ty = iterable else: raise TypingError( "unable to extend list, iterable is missing " "either *dtype*, *item_type* or *yield_type*." ) l = l.refine(ty) # Create the signature that we wanted this impl to have sig = typing.signature(types.void, l, iterable) return sig, select_impl()
def __call__(self, *args, **kwargs): if kwargs: raise TypingError("List() takes no keyword arguments") elif args: if not 0 <= len(args) <= 1: raise TypingError( "List() expected at most 1 argument, got {}".format( len(args))) rt = types.ListType(_guess_dtype(args[0])) self.attach_sig() return Signature(rt, args, None, pysig=self.pysig) else: item_type = types.undefined return types.ListType(item_type)
def typer(a, b): if not isinstance(a, types.Array) or not isinstance(b, types.Array): return if not all(x.ndim == 1 for x in (a, b)): raise TypingError("np.vdot() only supported on 1-D arrays") if not all(x.layout in 'CF' for x in (a, b)): warnings.warn("np.vdot() is faster on contiguous arrays, called on %s" % ((a, b),), NumbaPerformanceWarning) if not all(x.dtype == a.dtype for x in (a, b)): raise TypingError("np.vdot() arguments must all have " "the same dtype") if not isinstance(a.dtype, (types.Float, types.Complex)): raise TypingError("np.vdot() only supported on " "float and complex arrays") return a.dtype
def resolve_argsort(self, ary, args, kws): assert not args kwargs = dict(kws) kind = kwargs.pop('kind', types.StringLiteral('quicksort')) if not isinstance(kind, types.StringLiteral): raise TypingError('"kind" must be a string literal') if kwargs: msg = "Unsupported keywords: {!r}" raise TypingError(msg.format([k for k in kwargs.keys()])) if ary.ndim == 1: def argsort_stub(kind='quicksort'): pass pysig = utils.pysignature(argsort_stub) sig = signature(types.Array(types.intp, 1, 'C'), kind).replace(pysig=pysig) return sig
def pd_int64_index_append_overload(self, other): if not isinstance(self, Int64IndexType): return None _func_name = 'Method append().' ty_checker = TypeChecker(_func_name) if not isinstance(other, sdc_pandas_index_types): ty_checker.raise_exc(other, 'pandas index', 'other') if not check_types_comparable(self, other): raise TypingError('{} Not allowed for non comparable indexes. \ Given: self={}, other={}'.format(_func_name, self, other)) convert_other = not isinstance(other, types.Array) _, res_index_dtype = find_index_common_dtype(self, other) return_as_array_index = res_index_dtype is not types.int64 def pd_int64_index_append_impl(self, other): _other = other.values if convert_other == True else other # noqa new_index_data = hpat_arrays_append(self._data, _other) # this is only needed while some indexes are represented with arrays # TO-DO: support pd.Index() overload with dtype arg to create indexes if return_as_array_index == False: # noqa return pd.Int64Index(new_index_data) else: return new_index_data return pd_int64_index_append_impl
def impl_pop(l, index=-1): if not isinstance(l, types.ListType): return _check_for_none_typed(l, 'pop') indexty = INDEXTY # FIXME: this type check works, but it isn't clear why and if it optimal if (isinstance(index, int) or index in index_types or isinstance(index, types.Omitted)): def impl(l, index=-1): if len(l) == 0: raise IndexError("pop from empty list") index = handle_index(l, index) castedindex = _cast(index, indexty) status, item = _list_pop(l, castedindex) if status == ListStatus.LIST_OK: return _nonoptional(item) elif status == ListStatus.LIST_ERR_IMMUTABLE: raise ValueError("list is immutable") else: raise AssertionError("internal list error during pop") return impl else: raise TypingError("argument for pop must be an integer")
def csv_reader_infer_nb_arrow_type( filepath_or_buffer, delimiter=',', names=None, usecols=None, dtype=None, skiprows=None, parse_dates=False ): read_opts, parse_opts, convert_opts = get_pyarrow_read_csv_options( delimiter, names, usecols, dtype, skiprows, parse_dates) csv_reader = csv.open_csv(filepath_or_buffer, read_options=read_opts, parse_options=parse_opts, convert_options=convert_opts) table_schema = csv_reader.schema nb_arrow_column_types = [] for i, pa_data_type in enumerate(table_schema.types): nb_type = numpy_support.from_dtype(pa_data_type.to_pandas_dtype()) if isinstance(nb_type, types.PyObject): if pa_data_type == pa.string(): nb_type = StdStringViewType() else: raise TypingError("Cannot infer numba type for: ", pa_data_type, f"of column={table_schema.names[i]}") nb_arrow_column_types.append(nb_type) table_column_names = table_schema.names if not names else (names if usecols is None else usecols) arrow_table_type = ArrowTableType(nb_arrow_column_types, table_column_names) return arrow_table_type
def pd_range_index_equals_overload(self, other): if not isinstance(self, RangeIndexType): return None _func_name = 'Method equals().' if not isinstance(other, sdc_pandas_index_types): raise SDCLimitation( f"{_func_name} Unsupported parameter. Given 'other': {other}") if not check_types_comparable(self, other): raise TypingError('{} Not allowed for non comparable indexes. \ Given: self={}, other={}'.format(_func_name, self, other)) if isinstance(other, sdc_indexes_range_like): def pd_range_index_equals_impl(self, other): if len(self) != len(other): return False if len(self) == 0: return True if len(self) == 1: return self.start == other.start return self.start == other.start and self.step == other.step else: def pd_range_index_equals_impl(self, other): return sdc_numeric_indexes_equals(self, other) return pd_range_index_equals_impl
def to_scalar(x): if isinstance(x, (numba.types.Number, numba.types.Boolean)): return lambda x: x elif isinstance(x, numba.types.Array): return lambda x: x.item() else: raise TypingError(f"{x} must be a scalar compatible type.")
def get_nan_mask_overload(arr): _func_name = "Function: get_nan_mask" def get_nan_mask_via_isna_impl(arr): len_arr = len(arr) res = np.empty(len_arr, dtype=np.bool_) for i in numba.prange(len_arr): res[i] = isna(arr, i) return res if isinstance(arr, types.Array): dtype = arr.dtype if isinstance(dtype, types.Float): return lambda arr: np.isnan(arr) elif isinstance(dtype, (types.Boolean, types.Integer)): return lambda arr: np.zeros(len(arr), np.bool_) elif isinstance(dtype, (types.NPDatetime, types.NPTimedelta)): return get_nan_mask_via_isna_impl else: raise TypingError( '{} Not implemented for arrays with dtype: {}'.format( _func_name, dtype)) else: # for StringArrayType and other cases rely on isna implementation return get_nan_mask_via_isna_impl
def pd_positional_index_ne_overload(self, other): _func_name = 'Operator ne.' if not check_types_comparable(self, other): raise TypingError('{} Not allowed for non comparable indexes. \ Given: self={}, other={}'.format(_func_name, self, other)) self_is_positional_index = isinstance(self, PositionalIndexType) other_is_positional_index = isinstance(other, PositionalIndexType) possible_arg_types = (types.Array, types.Number) + sdc_pandas_index_types if not ( self_is_positional_index and other_is_positional_index or (self_is_positional_index and isinstance(other, possible_arg_types)) or (isinstance(self, possible_arg_types) and other_is_positional_index)): return None def pd_positional_index_ne_impl(self, other): eq_res = np.asarray( self == other) # FIXME_Numba#5157: remove np.asarray and return as list return list(~eq_res) return pd_positional_index_ne_impl
def pd_positional_index_reindex_overload(self, target, method=None, level=None, limit=None, tolerance=None): if not isinstance(self, PositionalIndexType): return None _func_name = 'Method reindex().' if not isinstance(target, sdc_pandas_index_types): raise SDCLimitation( f"{_func_name} Unsupported parameter. Given 'target': {target}") if not check_types_comparable(self, target): raise TypingError('{} Not allowed for non comparable indexes. \ Given: self={}, target={}'.format(_func_name, self, target)) def pd_positional_index_reindex_impl(self, target, method=None, level=None, limit=None, tolerance=None): return sdc_indexes_reindex(self, target=target, method=method, level=level, tolerance=tolerance) return pd_positional_index_reindex_impl
def _sentry_safe_cast(fromty, toty): """Check and raise TypingError if *fromty* cannot be safely cast to *toty*""" tyctxt = cpu_target.typing_context fromty, toty = map(types.unliteral, (fromty, toty)) by = tyctxt.can_convert(fromty, toty) def warn(): m = "unsafe cast from {} to {}. Precision may be lost." warnings.warn(m.format(fromty, toty), category=NumbaTypeSafetyWarning) isint = lambda x: isinstance(x, types.Integer) isflt = lambda x: isinstance(x, types.Float) iscmplx = lambda x: isinstance(x, types.Complex) # Only check against numeric types. if by is None or by > Conversion.safe: if isint(fromty) and isint(toty): # Accept if both types are ints warn() elif isint(fromty) and isflt(toty): # Accept if ints to floats warn() elif isflt(fromty) and isflt(toty): # Accept if floats to floats warn() elif iscmplx(fromty) and iscmplx(toty): # Accept if complex to complex warn() elif not isinstance(toty, types.Number): # Non-numbers warn() else: # Make it a hard error for numeric type that changes domain. m = "cannot safely cast {} to {}. Please cast explicitly." raise TypingError(m.format(fromty, toty))
def generic(self, args, kws): pysig = None if kws: if self.method_name == 'sum': if 'axis' in kws and 'dtype' not in kws: def sum_stub(arr, axis): pass pysig = utils.pysignature(sum_stub) elif 'dtype' in kws and 'axis' not in kws: def sum_stub(arr, dtype): pass pysig = utils.pysignature(sum_stub) elif 'dtype' in kws and 'axis' in kws: def sum_stub(arr, axis, dtype): pass pysig = utils.pysignature(sum_stub) elif self.method_name == 'argsort': def argsort_stub(arr, kind='quicksort'): pass pysig = utils.pysignature(argsort_stub) else: fmt = "numba doesn't support kwarg for {}" raise TypingError(fmt.format(self.method_name)) arr = args[0] # This will return a BoundFunction meth_ty = self.context.resolve_getattr(arr, self.method_name) # Resolve arguments on the bound function meth_sig = self.context.resolve_function_type(meth_ty, args[1:], kws) if meth_sig is not None: return meth_sig.as_function().replace(pysig=pysig)
def impl_delitem(l, index): if not isinstance(l, types.ListType): return _check_for_none_typed(l, 'delitem') if index in index_types: def integer_impl(l, index): cindex = _cast(handle_index(l, index), INDEXTY) status = _list_delitem(l, cindex) if status == ListStatus.LIST_OK: return elif status == ListStatus.LIST_ERR_IMMUTABLE: raise ValueError("list is immutable") else: raise AssertionError("internal list error during delitem") return integer_impl elif isinstance(index, types.SliceType): def slice_impl(l, index): slice_range = handle_slice(l, index) status = _list_delete_slice(l, slice_range.start, slice_range.stop, slice_range.step) if status == ListStatus.LIST_ERR_MUTATED: raise ValueError("list is immutable") return slice_impl else: raise TypingError("list indices must be integers or slices")
def ol_sum(iterable, start=0): # Cpython explicitly rejects strings, bytes and bytearrays # https://github.com/python/cpython/blob/3.9/Python/bltinmodule.c#L2310-L2329 # noqa: E501 error = None if isinstance(start, types.UnicodeType): error = ('strings', '') elif isinstance(start, types.Bytes): error = ('bytes', 'b') elif isinstance(start, types.ByteArray): error = ('bytearray', 'b') if error is not None: msg = "sum() can't sum {} [use {}''.join(seq) instead]".format(*error) raise TypingError(msg) # if the container is homogeneous then it's relatively easy to handle. if isinstance(iterable, (types.containers._HomogeneousTuple, types.List, types.ListType, types.Array, types.RangeType)): iterator = iter elif isinstance(iterable, (types.containers._HeterogeneousTuple)): # if container is heterogeneous then literal unroll and hope for the # best. iterator = literal_unroll else: return None def impl(iterable, start=0): acc = start for x in iterator(iterable): # This most likely widens the type, this is expected Numba behaviour acc = acc + x return acc return impl
def _ov_literally(obj): if isinstance(obj, types.Literal): lit = obj.literal_value return lambda obj: lit else: m = "Invalid use of non-Literal type in literally({})".format(obj) raise TypingError(m)
def _get_proper_func(func_32, func_64, dtype, dist_name="the given"): """ Most of the standard NumPy distributions that accept dtype argument only support either np.float32 or np.float64 as dtypes. This is a helper function that helps Numba select the proper underlying implementation according to provided dtype. """ if isinstance(dtype, types.Omitted): dtype = dtype.value np_dt = dtype if isinstance(dtype, type): nb_dt = from_dtype(np.dtype(dtype)) elif isinstance(dtype, types.NumberClass): nb_dt = dtype np_dt = as_dtype(nb_dt) if np_dt not in [np.float32, np.float64]: raise TypingError("Argument dtype is not one of the" + " expected type(s): " + " np.float32 or np.float64") if np_dt == np.float32: next_func = func_32 else: next_func = func_64 return next_func, nb_dt