Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #5
0
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
Beispiel #7
0
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)
Beispiel #8
0
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")
Beispiel #9
0
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)
Beispiel #10
0
    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)
Beispiel #11
0
    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
Beispiel #12
0
    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)
Beispiel #13
0
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()
Beispiel #14
0
 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)
Beispiel #15
0
 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
Beispiel #16
0
 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
Beispiel #17
0
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
Beispiel #18
0
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")
Beispiel #19
0
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
Beispiel #20
0
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
Beispiel #21
0
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.")
Beispiel #22
0
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
Beispiel #23
0
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
Beispiel #24
0
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))
Beispiel #26
0
    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")
Beispiel #28
0
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
Beispiel #29
0
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)
Beispiel #30
0
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