<commit_before>
import inspect
import uuid
import weakref
import collections

from numba import types, config

# Exported symbols
from .typing.typeof import typeof_impl
from .typing.templates import infer, infer_getattr
from .targets.imputils import (
    lower_builtin, lower_getattr, lower_getattr_generic,
    lower_setattr, lower_setattr_generic, lower_cast)
from .datamodel import models, register_default as register_model
from .pythonapi import box, unbox, reflect, NativeValue
from ._helperlib import _import_cython_function

def type_callable(func):
    """
    Decorate a function as implementing typing for the callable *func*.
    *func* can be a callable object (probably a global) or a string
    denoting a built-in operation (such 'getitem' or '__array_wrap__')
    """
    from .typing.templates import CallableTemplate, infer, infer_global
    if not callable(func) and not isinstance(func, str):
        raise TypeError("`func` should be a function or string")
    try:
        func_name = func.__name__
    except AttributeError:
        func_name = str(func)

    def decorate(typing_func):
        def generic(self):
            return typing_func(self.context)

        name = "%s_CallableTemplate" % (func_name,)
        bases = (CallableTemplate,)
        class_dict = dict(key=func, generic=generic)
        template = type(name, bases, class_dict)
        infer(template)
        if hasattr(func, '__module__'):
            infer_global(func, types.Function(template))

    return decorate


# By default, an *overload* does not have a cpython wrapper because it is not
# callable from python.
_overload_default_jit_options = {'no_cpython_wrapper': True}


def overload(func, jit_options={}, strict=True):
    """
    A decorator marking the decorated function as typing and implementing
    *func* in nopython mode.

    The decorated function will have the same formal parameters as *func*
    and be passed the Numba types of those parameters.  It should return
    a function implementing *func* for the given types.

    Here is an example implementing len() for tuple types::

        @overload(len)
        def tuple_len(seq):
            if isinstance(seq, types.BaseTuple):
                n = len(seq)
                def len_impl(seq):
                    return n
                return len_impl

    Compiler options can be passed as an dictionary using the **jit_options**
    argument.

    Overloading strictness (that the typing and implementing signatures match)
    is enforced by the **strict** keyword argument, it is recommended that this
    is set to True (default).
    """
    from .typing.templates import make_overload_template, infer_global

    # set default options
    opts = _overload_default_jit_options.copy()
    opts.update(jit_options)  # let user options override

    def decorate(overload_func):
        template = make_overload_template(func, overload_func, opts, strict)
        infer(template)
        if hasattr(func, '__module__'):
            infer_global(func, types.Function(template))
        return overload_func

    return decorate


def register_jitable(*args, **kwargs):
    """
    Register a regular python function that can be executed by the python
    interpreter and can be compiled into a nopython function when referenced
    by other jit'ed functions.  Can be used as::

        @register_jitable
        def foo(x, y):
            return x + y

    Or, with compiler options::<commit_msg>Update overload docs for the 2-tuple returning usage.<commit_after>
import inspect
import uuid
import weakref
import collections

from numba import types, config

# Exported symbols
from .typing.typeof import typeof_impl
from .typing.templates import infer, infer_getattr
from .targets.imputils import (
    lower_builtin, lower_getattr, lower_getattr_generic,
    lower_setattr, lower_setattr_generic, lower_cast)
from .datamodel import models, register_default as register_model
from .pythonapi import box, unbox, reflect, NativeValue
from ._helperlib import _import_cython_function

def type_callable(func):
    """
    Decorate a function as implementing typing for the callable *func*.
    *func* can be a callable object (probably a global) or a string
    denoting a built-in operation (such 'getitem' or '__array_wrap__')
    """
    from .typing.templates import CallableTemplate, infer, infer_global
    if not callable(func) and not isinstance(func, str):
        raise TypeError("`func` should be a function or string")
    try:
        func_name = func.__name__
    except AttributeError:
        func_name = str(func)

    def decorate(typing_func):
        def generic(self):
            return typing_func(self.context)

        name = "%s_CallableTemplate" % (func_name,)
        bases = (CallableTemplate,)
        class_dict = dict(key=func, generic=generic)
        template = type(name, bases, class_dict)
        infer(template)
        if hasattr(func, '__module__'):
            infer_global(func, types.Function(template))

    return decorate


# By default, an *overload* does not have a cpython wrapper because it is not
# callable from python.
_overload_default_jit_options = {'no_cpython_wrapper': True}


def overload(func, jit_options={}, strict=True):
    """
    A decorator marking the decorated function as typing and implementing
    *func* in nopython mode.

    The decorated function will have the same formal parameters as *func*
    and be passed the Numba types of those parameters.  It should return
    a function implementing *func* for the given types.

    Here is an example implementing len() for tuple types::

        @overload(len)
        def tuple_len(seq):
            if isinstance(seq, types.BaseTuple):
                n = len(seq)
                def len_impl(seq):
                    return n
                return len_impl

    Compiler options can be passed as an dictionary using the **jit_options**
    argument.

    Overloading strictness (that the typing and implementing signatures match)
    is enforced by the **strict** keyword argument, it is recommended that this
    is set to True (default).

    To handle implementation that accepts imprecise types, an overload
    definition can return 2-tuple of ``(signature, impl_function)``, where
    the ``signature`` is a ``typing.Signature`` specifying the precise
    signature to be used; and ``impl_function`` is the same implementation
    function as in the simple case.
    """
    from .typing.templates import make_overload_template, infer_global

    # set default options
    opts = _overload_default_jit_options.copy()
    opts.update(jit_options)  # let user options override

    def decorate(overload_func):
        template = make_overload_template(func, overload_func, opts, strict)
        infer(template)
        if hasattr(func, '__module__'):
            infer_global(func, types.Function(template))
        return overload_func

    return decorate


def register_jitable(*args, **kwargs):
    """
    Register a regular python function that can be executed by the python
    interpreter and can be compiled into a nopython function when referenced
    by other jit'ed functions.  Can be used as::

        @register_jitable
        def foo(x, y):
            return x + y

    Or, with compiler options::
{'fraction_non_alphanumeric': 0.07136034929731205, 'fraction_numerical': 0.0002728885250375222, 'mean_word_length': 3.1718838929994306, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4357645', 'n_tokens_mistral': 2029, 'n_tokens_neox': 1960, 'n_words': 737}