Пример #1
0
    def decorate(fn, add_positional_parameters=()):

        spec = inspect_getfullargspec(fn)
        if add_positional_parameters:
            spec.args.extend(add_positional_parameters)

        metadata = dict(
            __target_fn="__target_fn", __orig_fn="__orig_fn", name=fn.__name__
        )
        metadata.update(format_argspec_plus(spec, grouped=False))
        code = (
            """\
def %(name)s(%(args)s):
    return %(__target_fn)s(%(__orig_fn)s, %(apply_kw)s)
"""
            % metadata
        )
        decorated = _exec_code_in_env(
            code, {"__target_fn": target, "__orig_fn": fn}, fn.__name__
        )
        if not add_positional_parameters:
            decorated.__defaults__ = getattr(fn, "__func__", fn).__defaults__
            decorated.__wrapped__ = fn
            return update_wrapper(decorated, fn)
        else:
            # this is the pytest hacky part.  don't do a full update wrapper
            # because pytest is really being sneaky about finding the args
            # for the wrapped function
            decorated.__module__ = fn.__module__
            decorated.__name__ = fn.__name__
            if hasattr(fn, "pytestmark"):
                decorated.pytestmark = fn.pytestmark
            return decorated
Пример #2
0
    def instrument(buf: TextIO, name: str, clslevel: bool = False) -> None:
        fn = getattr(target_cls, name)

        overloads = _grab_overloads(fn)

        for overload in overloads:
            buf.write(overload)

        spec = compat.inspect_getfullargspec(fn)

        iscoroutine = inspect.iscoroutinefunction(fn)

        if spec.defaults or spec.kwonlydefaults:
            elem = list(spec)

            if spec.defaults:
                new_defaults = tuple(
                    _repr_sym("util.EMPTY_DICT"
                              ) if df is util.EMPTY_DICT else df
                    for df in spec.defaults)
                elem[3] = new_defaults

            if spec.kwonlydefaults:
                new_kwonlydefaults = {
                    name: _repr_sym("util.EMPTY_DICT")
                    if df is util.EMPTY_DICT else df
                    for name, df in spec.kwonlydefaults.items()
                }
                elem[5] = new_kwonlydefaults

            spec = compat.FullArgSpec(*elem)

        caller_argspec = format_argspec_plus(spec, grouped=False)

        metadata = {
            "name":
            fn.__name__,
            "async":
            "async " if iscoroutine else "",
            "await":
            "await " if iscoroutine else "",
            "apply_pos_proxied":
            caller_argspec["apply_pos_proxied"],
            "target_cls_name":
            target_cls.__name__,
            "apply_kw_proxied":
            caller_argspec["apply_kw_proxied"],
            "grouped_args":
            caller_argspec["grouped_args"],
            "self_arg":
            caller_argspec["self_arg"],
            "doc":
            textwrap.indent(
                inject_docstring_text(
                    fn.__doc__,
                    textwrap.indent(
                        ".. container:: class_bases\n\n"
                        f"    Proxied for the {target_cls_sphinx_name} "
                        "class on \n"
                        f"    behalf of the {proxy_cls_sphinx_name} "
                        "class.",
                        "    ",
                    ),
                    1,
                ),
                "    ",
            ).lstrip(),
        }

        if clslevel:
            code = (
                "@classmethod\n"
                "%(async)sdef %(name)s%(grouped_args)s:\n"
                '    r"""%(doc)s\n    """  # noqa: E501\n\n'
                "    return %(await)s%(target_cls_name)s.%(name)s(%(apply_kw_proxied)s)\n\n"  # noqa: E501
                % metadata)
        else:
            code = (
                "%(async)sdef %(name)s%(grouped_args)s:\n"
                '    r"""%(doc)s\n    """  # noqa: E501\n\n'
                "    return %(await)s%(self_arg)s._proxied.%(name)s(%(apply_kw_proxied)s)\n\n"  # noqa: E501
                % metadata)

        buf.write(textwrap.indent(code, "    "))