Ejemplo n.º 1
0
def test_define_function_signature_works_with_conflicts():
    def accepts_everything(*args, **kwargs):
        pass

    define_function_signature(
        "hello",
        "A docstring for hello",
        FullArgSpec(
            args=("f", ),
            varargs=None,
            varkw=None,
            defaults=None,
            kwonlyargs=[],
            kwonlydefaults=None,
            annotations={},
        ),
    )(accepts_everything)(1)

    define_function_signature(
        "hello",
        "A docstring for hello",
        FullArgSpec(
            args=(),
            varargs="f",
            varkw=None,
            defaults=None,
            kwonlyargs=[],
            kwonlydefaults=None,
            annotations={},
        ),
    )(accepts_everything)(1)

    define_function_signature(
        "hello",
        "A docstring for hello",
        FullArgSpec(
            args=(),
            varargs=None,
            varkw="f",
            defaults=None,
            kwonlyargs=[],
            kwonlydefaults=None,
            annotations={},
        ),
    )(accepts_everything)()

    define_function_signature(
        "hello",
        "A docstring for hello",
        FullArgSpec(
            args=("f", "f_3"),
            varargs="f_1",
            varkw="f_2",
            defaults=None,
            kwonlyargs=[],
            kwonlydefaults=None,
            annotations={},
        ),
    )(accepts_everything)(1, 2)
Ejemplo n.º 2
0
 def _getargspec_init(method: Callable) -> FullArgSpec:
     try:
         return inspect.getfullargspec(method)
     except TypeError:
         if method is object.__init__:
             return FullArgSpec(['self'], None, None, None, [], None, {})
         else:
             return FullArgSpec(['self'], 'args', 'kwargs', None, [], None,
                                {})
Ejemplo n.º 3
0
 def getfullargspec(func):
     args, varargs, varkw, defaults = inspect.getargspec(func)
     return FullArgSpec(
         args,
         varargs,
         varkw,
         defaults,
         [],
         None,
         getattr(func, "__annotations__", {}),
     )
Ejemplo n.º 4
0
def _update_configurable_argspec(argspec: inspect.FullArgSpec,
                                 cfg_param: str) -> inspect.FullArgSpec:
    """Return an updated :class:`FullArgSpec` for a configurable function."""
    return argspec._replace(
        kwonlyargs=argspec.kwonlyargs
        and [arg for arg in argspec.kwonlyargs if arg != cfg_param],
        kwonlydefaults=argspec.kwonlydefaults and
        {k: v
         for k, v in argspec.kwonlydefaults.items() if k != cfg_param},
        annotations=argspec.annotations
        and {k: v
             for k, v in argspec.annotations.items() if k != cfg_param})
Ejemplo n.º 5
0
 def test_func_signature(self):
     """Test that __init__ and run signatures are correct."""
     init_spec = getfullargspec(HorovodRunner.__init__)
     self.assertEquals(
         init_spec,
         FullArgSpec(
             args=['self'],
             varargs=None,
             varkw=None,
             defaults=None,
             kwonlyargs=['np', 'driver_log_verbosity'],
             kwonlydefaults={'driver_log_verbosity': 'log_callback_only'},
             annotations={}))
     run_spec = getfullargspec(HorovodRunner.run)
     self.assertEquals(
         run_spec,
         FullArgSpec(args=['self', 'main'],
                     varargs=None,
                     varkw='kwargs',
                     defaults=None,
                     kwonlyargs=[],
                     kwonlydefaults=None,
                     annotations={}))
Ejemplo n.º 6
0
def test_define_function_signature_validates_function_name():
    with raises(ValueError):
        define_function_signature(
            "hello world",
            None,
            FullArgSpec(
                args=["a", "b"],
                varargs=None,
                varkw=None,
                defaults=None,
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )
Ejemplo n.º 7
0
def create_dispatcher(
    params_arity, args=None, varargs=None, keywords=None, defaults=None
) -> FunctionDispatcher:

    return FunctionDispatcher(
        FullArgSpec(
            args=args,
            varargs=varargs,
            varkw=keywords,
            defaults=defaults,
            kwonlyargs=[],
            kwonlydefaults={},
            annotations={},
        ),
        params_arity,
    )
Ejemplo n.º 8
0
 def getfullargspec(func):
     import inspect
     args, varargs, varkw, defaults = inspect.getargspec(func)
     return FullArgSpec(args, varargs, varkw, defaults, [], None,
                        getattr(func, '__annotations__', {}))
Ejemplo n.º 9
0
def getfullargspec(func):
    """Get the names and default values of a callable object's parameters.

    A tuple of seven things is returned:
    (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
    'args' is a list of the parameter names.
    'varargs' and 'varkw' are the names of the * and ** parameters or None.
    'defaults' is an n-tuple of the default values of the last n parameters.
    'kwonlyargs' is a list of keyword-only parameter names.
    'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
    'annotations' is a dictionary mapping parameter names to annotations.

    Notable differences from inspect.signature():
      - the "self" parameter is always reported, even for bound methods
      - wrapper chains defined by __wrapped__ *not* unwrapped automatically
    """

    try:
        # Re: `skip_bound_arg=False`
        #
        # There is a notable difference in behaviour between getfullargspec
        # and Signature: the former always returns 'self' parameter for bound
        # methods, whereas the Signature always shows the actual calling
        # signature of the passed object.
        #
        # To simulate this behaviour, we "unbind" bound methods, to trick
        # inspect.signature to always return their first parameter ("self",
        # usually)

        # Re: `follow_wrapper_chains=False`
        #
        # getfullargspec() historically ignored __wrapped__ attributes,
        # so we ensure that remains the case in 3.3+

        sig = _signature_from_callable(
            func, follow_wrapper_chains=False, skip_bound_arg=False, sigcls=Signature
        )
    except Exception:
        # Most of the times 'signature' will raise ValueError.
        # But, it can also raise AttributeError, and, maybe something
        # else. So to be fully backwards compatible, we catch all
        # possible exceptions here, and reraise a TypeError.
        raise TypeError("unsupported callable") # from ex

    args = []
    varargs = None
    varkw = None
    kwonlyargs = []
    defaults = ()
    annotations = {}
    defaults = ()
    kwdefaults = {}

    if sig.return_annotation is not sig.empty:
        annotations["return"] = sig.return_annotation

    for param in sig.parameters.values():
        kind = param.kind
        name = param.name

        if kind is POSITIONAL_ONLY:
            args.append(name)
        elif kind is POSITIONAL_OR_KEYWORD:
            args.append(name)
            if param.default is not param.empty:
                defaults += (param.default,)
        elif kind is VAR_POSITIONAL:
            varargs = name
        elif kind is KEYWORD_ONLY:
            kwonlyargs.append(name)
            if param.default is not param.empty:
                kwdefaults[name] = param.default
        elif kind is VAR_KEYWORD:
            varkw = name

        if param.annotation is not param.empty:
            annotations[name] = param.annotation

    if not kwdefaults:
        # compatibility with 'func.__kwdefaults__'
        kwdefaults = None

    if not defaults:
        # compatibility with 'func.__defaults__'
        defaults = None

    return FullArgSpec(
        args, varargs, varkw, defaults, kwonlyargs, kwdefaults, annotations
    )
Ejemplo n.º 10
0
 def getfullargspec(func):
     import inspect
     args, varargs, varkw, defaults = inspect.getargspec(func)
     return FullArgSpec(args, varargs, varkw, defaults, [], None, {})
Ejemplo n.º 11
0
    def getfullargspec(f, skip_bound_arg=False, follow_wrapped=True):
        """
        This method adds `skip_bound_arg` argument to `getfullargspec` so that it is capable of skipping the 'self'
        parameter of bound methods, like `signature` does.

        This is the version for python 3. It is mostly the same code than in `inspect.getfullargspec`, except that
         - `skip_bound_arg` is not forced to `False`
         - Errors are improved if possible: if the function is a built-in the error raised is an explicit
           `IsBuiltInError`.

        :param f:
        :param skip_bound_arg:
        :param follow_wrapped:
        :return:
        """
        if skip_bound_arg:
            try:
                sig = signature(f, follow_wrapped=follow_wrapped)
            except ValueError as e:
                if _signature_is_builtin(f):
                    raise IsBuiltInError(f)
                elif isinstance(f, partial) and _signature_is_builtin(f.func):
                    raise IsBuiltInError(f)
                elif _is_builtin_value_error(e):
                    raise IsBuiltInError(f)
                else:
                    raise

            args = []
            varargs = None
            varkw = None
            kwonlyargs = []
            annotations = {}
            defaults = ()
            kwdefaults = {}

            if sig.return_annotation is not sig.empty:
                annotations['return'] = sig.return_annotation

            for p in sig.parameters.values():
                kind = p.kind
                name = p.name

                if kind is p.POSITIONAL_ONLY:
                    args.append(name)
                elif kind is p.POSITIONAL_OR_KEYWORD:
                    args.append(name)
                    if p.default is not p.empty:
                        defaults += (p.default, )
                elif kind is p.VAR_POSITIONAL:
                    varargs = name
                elif kind is p.KEYWORD_ONLY:
                    kwonlyargs.append(name)
                    if p.default is not p.empty:
                        kwdefaults[name] = p.default
                elif kind is p.VAR_KEYWORD:
                    varkw = name

                if p.annotation is not p.empty:
                    annotations[name] = p.annotation

            if not kwdefaults:
                # compatibility with 'func.__kwdefaults__'
                kwdefaults = None

            if not defaults:
                # compatibility with 'func.__defaults__'
                defaults = None

            return FullArgSpec(args, varargs, varkw, defaults, kwonlyargs,
                               kwdefaults, annotations)

        else:
            # use getfullargspec
            raise NotImplementedError()
Ejemplo n.º 12
0
    def getfullargspec(f, skip_bound_arg=False, follow_wrapped=True):
        """
        This method adds `skip_bound_arg` argument to `getfullargspec` so that it is capable of skipping the 'self'
        parameter of bound methods, like `signature` does.

        This version is for python 2. It is based on `getargspec`.

        It is also enhanced to support `partial` objects because before Python 3.4, getargspec() did't work for
        functools.partial, so it needs to be handled separately.

        Finally when some signatures cant be found, if the function is a built-in the error raised is an explicit
        `IsBuiltInError`.

        :param f:
        :param skip_bound_arg:
        :param follow_wrapped:
        :return:
        """
        if follow_wrapped:
            try:
                # Was this function wrapped by a decorator?
                wrapped = f.__wrapped__
            except AttributeError:
                pass
            else:
                return getfullargspec(wrapped,
                                      skip_bound_arg=skip_bound_arg,
                                      follow_wrapped=follow_wrapped)

        try:
            if isinstance(f, partial):
                # (1) partial
                # from https://github.com/dsacre/pyliblo/commit/e897f9987dc97fc678d61ac0e16fe79c6a7dffc0#diff-2be46de1531c648b0e936ccfa59f1692R262
                # before Python 3.4, getargspec() did't work for functools.partial, so it needs to be handled separately
                p = f
                f = f.func
                args, varpos, varkw, defaults = getargspec(f)
                nb_args_before = len(args)
                nb_pos_removed = len(p.args)
                args = args[nb_pos_removed:]
                if defaults is None:
                    if p.keywords is not None and len(p.keywords) > 0:
                        nb_args_after = nb_args_before - nb_pos_removed
                        args = list(args)
                        end = nb_args_after
                        i = 0
                        while i < end:
                            if args[i] in p.keywords:
                                del args[i]
                                end -= 1
                            else:
                                i += 1
                else:
                    nb_without_default_before = nb_args_before - len(defaults)
                    _diff = nb_pos_removed - nb_without_default_before
                    nb_pos_defaults_removed = max(0, _diff)
                    defaults = defaults[nb_pos_defaults_removed:]
                    if p.keywords is not None and len(p.keywords) > 0:
                        nb_args_after = nb_args_before - nb_pos_removed
                        nb_without_defaults_after = max(0, -_diff)
                        args = list(args)
                        defaults = list(defaults)
                        end = nb_args_after
                        i = 0
                        while i < end:
                            if args[i] in p.keywords:
                                del args[i]
                                del defaults[i - nb_without_defaults_after]
                                end -= 1
                            else:
                                i += 1

                return FullArgSpec(args, varpos, varkw, defaults, None, None,
                                   None)

            else:
                # (2) nominal case
                args, varpos, varkw, defaults = getargspec(f)
                try:
                    # if bound instance or class method
                    if skip_bound_arg and f.__self__ is not None:
                        args = args[1:]
                except AttributeError:
                    pass
                return FullArgSpec(args, varpos, varkw, defaults, None, None,
                                   None)

        except TypeError as e:
            # built-ins...
            if isinstance(f, _NonUserDefinedCallables):
                # see https://docs.python.org/2/library/types.html#types.BuiltinFunctionType
                # note "built-in" means "C built-in"
                raise IsBuiltInError(f)
            else:
                # try:
                #     declaring_class = f.__objclass__
                #     # this does not make us make any progress... skip
                # except AttributeError:
                if e.args[0].endswith("> is not a Python function"):
                    raise IsBuiltInError(f)
                else:
                    raise ValueError("unknown case")