Ejemplo n.º 1
0
    def test_dc_on_top_of_non_dc(self, decl_base: Type[DeclarativeBase]):
        class Person(decl_base):
            __tablename__ = "person"
            person_id: Mapped[int] = mapped_column(primary_key=True)
            name: Mapped[str]
            type: Mapped[str] = mapped_column()

            __mapper_args__ = {"polymorphic_on": type}

        class Engineer(MappedAsDataclass, Person):
            __tablename__ = "engineer"

            person_id: Mapped[int] = mapped_column(
                ForeignKey("person.person_id"), primary_key=True, init=False
            )

            status: Mapped[str] = mapped_column(String(30))
            engineer_name: Mapped[str]
            primary_language: Mapped[str]

        e1 = Engineer("st", "en", "pl")
        eq_(e1.status, "st")
        eq_(e1.engineer_name, "en")
        eq_(e1.primary_language, "pl")

        eq_(
            pyinspect.getfullargspec(Person.__init__),
            # the boring **kw __init__
            pyinspect.FullArgSpec(
                args=["self"],
                varargs=None,
                varkw="kwargs",
                defaults=None,
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )

        eq_(
            pyinspect.getfullargspec(Engineer.__init__),
            # the exciting dataclasses __init__
            pyinspect.FullArgSpec(
                args=["self", "status", "engineer_name", "primary_language"],
                varargs=None,
                varkw=None,
                defaults=None,
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )
Ejemplo n.º 2
0
 def getargspec(func):
     """Like inspect.getargspec but supports functools.partial as well."""
     if inspect.ismethod(func):
         func = func.__func__
     if type(func) is partial:
         orig_func = func.func
         argspec = getargspec(orig_func)
         args = list(argspec[0])
         defaults = list(argspec[3] or ())
         kwoargs = list(argspec[4])
         kwodefs = dict(argspec[5] or {})
         if func.args:
             args = args[len(func.args):]
         for arg in func.keywords or ():
             try:
                 i = args.index(arg) - len(args)
                 del args[i]
                 try:
                     del defaults[i]
                 except IndexError:
                     pass
             except ValueError:  # must be a kwonly arg
                 i = kwoargs.index(arg)
                 del kwoargs[i]
                 del kwodefs[arg]
         return inspect.FullArgSpec(args, argspec[1], argspec[2],
                                    tuple(defaults), kwoargs, kwodefs,
                                    argspec[6])
     while hasattr(func, '__wrapped__'):
         func = func.__wrapped__
     if not inspect.isfunction(func):
         raise TypeError('%r is not a Python function' % func)
     return inspect.getfullargspec(func)
Ejemplo n.º 3
0
def getargspec(func: Callable) -> Any:
    """Like inspect.getfullargspec but supports bound methods, and wrapped
    methods."""
    warnings.warn('sphinx.ext.inspect.getargspec() is deprecated',
                  RemovedInSphinx50Warning,
                  stacklevel=2)
    # On 3.5+, signature(int) or similar raises ValueError. On 3.4, it
    # succeeds with a bogus signature. We want a TypeError uniformly, to
    # match historical behavior.
    if (isinstance(func, type) and is_builtin_class_method(func, "__new__")
            and is_builtin_class_method(func, "__init__")):
        raise TypeError(
            "can't compute signature for built-in type {}".format(func))

    sig = inspect.signature(func)

    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 Parameter.POSITIONAL_ONLY:
            args.append(name)
        elif kind is Parameter.POSITIONAL_OR_KEYWORD:
            args.append(name)
            if param.default is not param.empty:
                defaults += (param.default, )  # type: ignore
        elif kind is Parameter.VAR_POSITIONAL:
            varargs = name
        elif kind is Parameter.KEYWORD_ONLY:
            kwonlyargs.append(name)
            if param.default is not param.empty:
                kwdefaults[name] = param.default
        elif kind is Parameter.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 inspect.FullArgSpec(args, varargs, varkw, defaults, kwonlyargs,
                               kwdefaults, annotations)
Ejemplo n.º 4
0
def getfullargspec(func):
    # Python 3: Use get_signature instead.
    assert sys.version_info < (
        3, ), 'This method should not be used in Python 3'
    try:
        return _original_getfullargspec(func)
    except TypeError:
        if isinstance(func, type):
            argspec = getfullargspec(func.__init__)
            del argspec.args[0]
            return argspec
        elif callable(func):
            try:
                return _original_getfullargspec(func.__call__)
            except TypeError:
                # Return an ArgSpec with at least one positional argument,
                # and any number of other (positional or keyword) arguments
                # whose name won't match any real argument.
                # Arguments with the %unknown% prefix will be ignored in the type
                # checking code.
                if _use_full_argspec:
                    return inspect.FullArgSpec(['_'], '__unknown__varargs',
                                               '__unknown__keywords', (), [],
                                               {}, {})
                else:  # Python 2
                    return inspect.ArgSpec(['_'], '__unknown__varargs',
                                           '__unknown__keywords', ())
        else:
            raise
Ejemplo n.º 5
0
    def visit_FunctionDef(self, node):
        """
        Save an argSpec for user defined functions
        """
        args = [a.arg for a in node.args.args]
        if node.args.kwonlyargs:
            raise ParseError(
                f"Keyword-only arguments not supported in Zbursh: def {node.name}, line {node.lineno}"
            )
        if node.args.vararg:
            raise ParseError(
                f"Variable arguments not supported in Zbursh: def {node.name}, line {node.lineno}"
            )
        if node.args.kw_defaults:
            raise ParseError(
                f"keyword default arguments not supported in Zbrush: def {node.name}, line {node.lineno}"
            )
        if node.args.defaults:
            raise ParseError(
                f"default arguments not supported in Zbrush: def {node.name}, line {node.lineno}"
            )
        if node.args.kwarg:
            raise ParseError(
                f"keyword arguments not allowed in Zbrush user : def {node.name}, line {node.lineno}"
            )

        self.user_functions[node.name] = inspect.FullArgSpec(
            args=args,
            varargs=None,
            varkw=None,
            defaults=None,
            kwonlyargs=None,
            kwonlydefaults=None,
            annotations={})
Ejemplo n.º 6
0
def getargspec(func: Callable) -> Any:
    """Like inspect.getfullargspec but supports bound methods, and wrapped
    methods."""
    warnings.warn('sphinx.ext.inspect.getargspec() is deprecated',
                  RemovedInSphinx50Warning,
                  stacklevel=2)

    sig = inspect.signature(func)

    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 Parameter.POSITIONAL_ONLY:
            args.append(name)
        elif kind is Parameter.POSITIONAL_OR_KEYWORD:
            args.append(name)
            if param.default is not param.empty:
                defaults += (param.default, )  # type: ignore
        elif kind is Parameter.VAR_POSITIONAL:
            varargs = name
        elif kind is Parameter.KEYWORD_ONLY:
            kwonlyargs.append(name)
            if param.default is not param.empty:
                kwdefaults[name] = param.default
        elif kind is Parameter.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 inspect.FullArgSpec(args, varargs, varkw, defaults, kwonlyargs,
                               kwdefaults, annotations)
Ejemplo n.º 7
0
    def _gen_callable_matrix_adapter(self, f_spec):
        f_args_spec_struct = OrderedStructDict(
            f_spec.arg_spec._asdict()).deepcopy()
        f_args_spec_struct.kwonlyargs.append('param_struct')
        if f_args_spec_struct.kwonlydefaults:
            f_args_spec_struct.kwonlydefaults.update({'param_struct': None})
        else:
            f_args_spec_struct.kwonlydefaults = {'param_struct': None}

        f_args_spec = inspect.FullArgSpec(**f_args_spec_struct)
        adapter = make_function(f_args_spec, name='adapter')
        return adapter
Ejemplo n.º 8
0
def test_getfullargspec():
    instance = Instance(TEST_BYTES)
    assert instance.exports.sum.getfullargspec == inspect.FullArgSpec(
        args=['x0', 'x1'],
        varargs=None,
        varkw=None,
        defaults=None,
        kwonlyargs=None,
        kwonlydefaults=None,
        annotations={
            'x0': Type.I32,
            'x1': Type.I32,
            'return': Type.I32
        })
Ejemplo n.º 9
0
    def getargspec(func):
        """Like inspect.getfullargspec but supports bound methods, and wrapped
        methods."""
        sig = inspect.signature(func)

        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 inspect.Parameter.POSITIONAL_ONLY:
                args.append(name)
            elif kind is inspect.Parameter.POSITIONAL_OR_KEYWORD:
                args.append(name)
                if param.default is not param.empty:
                    defaults += (param.default,)
            elif kind is inspect.Parameter.VAR_POSITIONAL:
                varargs = name
            elif kind is inspect.Parameter.KEYWORD_ONLY:
                kwonlyargs.append(name)
                if param.default is not param.empty:
                    kwdefaults[name] = param.default
            elif kind is inspect.Parameter.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 inspect.FullArgSpec(args, varargs, varkw, defaults,
                                   kwonlyargs, kwdefaults, annotations)
Ejemplo n.º 10
0
def test_signature(methods, method, arguments):
    methods.remove(method)

    args = {
        "args": ["self"],
        "varargs": None,
        "varkw": None,
        "defaults": None,
        "kwonlyargs": [],
        "kwonlydefaults": None,
        "annotations": {},
        **arguments
    }
    sig = inspect.FullArgSpec(**args)
    spec = inspect.getfullargspec(getattr(ThermalPrinter, method))
    assert spec == sig
Ejemplo n.º 11
0
def arginfo(callable):
    """Get information about the arguments of a callable.

    Returns a :class:`inspect.FullArgSpec` object as for
    :func:`inspect.getfullargspec`.

    :func:`inspect.getfullargspec` returns information about the arguments
    of a function. arginfo also works for classes and instances with a
    __call__ defined. Unlike getfullargspec, arginfo treats bound methods
    like functions, so that the self argument is not reported.

    arginfo returns ``None`` if given something that is not callable.

    arginfo caches previous calls (except for instances with a
    __call__), making calling it repeatedly cheap.

    This was originally inspired by the pytest.core varnames() function,
    but has been completely rewritten to handle class constructors,
    also show other getarginfo() information, and for readability.
    """
    try:
        return arginfo._cache[callable]
    except KeyError:
        # Try to get __call__ function from the cache.
        try:
            return arginfo._cache[callable.__call__]
        except (AttributeError, KeyError):
            pass
    func, cache_key, remove_self = get_callable_info(callable)
    if func is None:
        return None
    result = inspect.getfullargspec(func)
    if remove_self:
        args = result.args[1:]
        result = inspect.FullArgSpec(
            args,
            result.varargs,
            result.varkw,
            result.defaults,
            result.kwonlyargs,
            result.kwonlydefaults,
            result.annotations,
        )
    arginfo._cache[cache_key] = result
    return result
Ejemplo n.º 12
0
def getfullargspec(func):
    if func in (_np.empty_like, _np.ones_like, _np.zeros_like):
        if func is _np.empty_like:
            sig = inspect._signature_fromstr(
                inspect.Signature, func,
                func.__doc__.strip().split('\n', maxsplit=1)[0])
        else:
            sig = inspect.signature(func)
        return inspect.FullArgSpec(
            list(sig.parameters.keys()),  # args
            None,  # varargs
            None,  # varkw
            tuple(v.default for v in sig.parameters.values()
                  if v.default is not inspect._empty),  # defaults
            [],  # knwonlyargs
            {},  # kwonlydefaults
            {},  # annotations
        )
    else:
        return _inspect_getfullargspec(func)
Ejemplo n.º 13
0
def get_cached_func_spec(func, bypass_cache=False, reset_cache=False, clear_cache=False):
    try:
        f_spec = func._f_spec
        if f_spec is not None and not any((bypass_cache, reset_cache, clear_cache)):
            return func._f_spec  # use cached _f_spec
    except AttributeError:
        pass

    f_signature = inspect.signature(func)

    f_args_spec_dict = OrderedDict(inspect.getfullargspec(func)._asdict())
    if isinstance(func, types.MethodType):
        f_args_spec_dict['args'] = f_args_spec_dict['args'][1:]
    f_args_spec = inspect.FullArgSpec(**f_args_spec_dict)

    f_pos_only_params = [param_name for param_name, param in f_signature.parameters.items() if
                         param.kind is Parameter.POSITIONAL_ONLY]
    f_pos_or_kw_params = [param_name for param_name, param in f_signature.parameters.items() if
                          param.kind is Parameter.POSITIONAL_OR_KEYWORD]
    f_kw_only_params = [param_name for param_name, param in f_signature.parameters.items() if
                        param.kind is Parameter.KEYWORD_ONLY]
    f_all_kw_params = f_pos_or_kw_params + f_kw_only_params
    f_all_kw_default = {param_name: param.default for param_name, param in f_signature.parameters.items() if
                        param.default is not Parameter.empty}
    f_type = type(func)

    f_spec = _FSpecNamedTup(f_signature, f_args_spec, f_pos_only_params, f_pos_or_kw_params, f_kw_only_params,
                            f_all_kw_params, f_all_kw_default, f_type)

    cache_f_spec = f_spec if not clear_cache else None
    if (not bypass_cache) or reset_cache or clear_cache:
        if isinstance(func, types.MethodType):
            func.__func__._f_spec = cache_f_spec  # cache f_spec as function attribute
        else:
            func._f_spec = cache_f_spec

    return f_spec
Ejemplo n.º 14
0
def getfullargspec(func):
    """Get the names and default values of a function's arguments.

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

    The first four items in the tuple correspond to getargspec().
    """

    if inspect.ismethod(func):
        func = func.__func__
    if not inspect.isfunction(func):
        raise TypeError('arg is not a Python function')
    args, varargs, kwonlyargs, varkw = inspect._getfullargs(
        sys.get_func_code(func))
    return inspect.FullArgSpec(args, varargs, varkw, func.__defaults__,
                               kwonlyargs, func.__kwdefaults__,
                               func.__annotations__)
Ejemplo n.º 15
0
    def test_basic_constructor_repr_base_cls(
        self, dc_decl_base: Type[MappedAsDataclass]
    ):
        class A(dc_decl_base):
            __tablename__ = "a"

            id: Mapped[int] = mapped_column(primary_key=True, init=False)
            data: Mapped[str]

            x: Mapped[Optional[int]] = mapped_column(default=None)

            bs: Mapped[List["B"]] = relationship(  # noqa: F821
                default_factory=list
            )

        class B(dc_decl_base):
            __tablename__ = "b"

            id: Mapped[int] = mapped_column(primary_key=True, init=False)
            data: Mapped[str]
            a_id: Mapped[Optional[int]] = mapped_column(
                ForeignKey("a.id"), init=False
            )
            x: Mapped[Optional[int]] = mapped_column(default=None)

        A.__qualname__ = "some_module.A"
        B.__qualname__ = "some_module.B"

        eq_(
            pyinspect.getfullargspec(A.__init__),
            pyinspect.FullArgSpec(
                args=["self", "data", "x", "bs"],
                varargs=None,
                varkw=None,
                defaults=(None, mock.ANY),
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )
        eq_(
            pyinspect.getfullargspec(B.__init__),
            pyinspect.FullArgSpec(
                args=["self", "data", "x"],
                varargs=None,
                varkw=None,
                defaults=(None,),
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )

        a2 = A("10", x=5, bs=[B("data1"), B("data2", x=12)])
        eq_(
            repr(a2),
            "some_module.A(id=None, data='10', x=5, "
            "bs=[some_module.B(id=None, data='data1', a_id=None, x=None), "
            "some_module.B(id=None, data='data2', a_id=None, x=12)])",
        )

        a3 = A("data")
        eq_(repr(a3), "some_module.A(id=None, data='data', x=None, bs=[])")
Ejemplo n.º 16
0
def has_type_depth(val, ty, depth):
    if depth > flags.CHECK_DEPTH:
        return True
    elif ty is TypeVariable:
        return True
    elif ty is Self:
        return True
    elif ty is Dyn:
        return True
    elif ty is InferBottom:
        return False
    elif ty is Void:
        return val == None
    elif ty is Int:
        return isinstance(val, int) or (not flags.FLAT_PRIMITIVES and has_type(val, Bool))
    elif ty is Bytes:
        return isinstance(val, bytes)
    elif ty is Bool:
        return isinstance(val, bool)
    elif ty is Float:
        return isinstance(val, float) or (not flags.FLAT_PRIMITIVES and has_type(val, Int))
    elif ty is Complex:
        return isinstance(val, complex) or (not flags.FLAT_PRIMITIVES and has_type(val, Float))
    elif ty is String:
        return isinstance(val, str)
    elif isinstance(ty, Function):
        if callable(val): 
            return True
        else: return False

        if val.__class__ is types.MethodType: # Only true for bound methods
            spec = getfullargspec(val)
            new_spec = inspect.FullArgSpec(spec.args[1:], spec.varargs, spec.varkw, 
                                           spec.defaults, spec.kwonlyargs, 
                                           spec.kwonlydefaults, spec.annotations)
            return func_has_type(new_spec, ty)
        elif val.__class__ is types.FunctionType: # Normal function
            return func_has_type(getfullargspec(val), ty)
        elif val.__class__ is type: 
            if val.__init__.__class__ is types.FunctionType:
                spec = getfullargspec(val.__init__)
                new_spec = inspect.FullArgSpec(spec.args[1:], spec.varargs, spec.varkw, 
                                               spec.defaults, spec.kwonlyargs, 
                                               spec.kwonlydefaults, spec.annotations)
                return func_has_type(new_spec, ty)
            else: return True
        elif val.__class__ is types.BuiltinFunctionType:
            return True
        elif hasattr(val, '__call__'):
            if val.__call__.__class__ is types.MethodType:
                spec = getfullargspec(val.__call__)
                new_spec = inspect.FullArgSpec(spec.args[1:], spec.varargs, spec.varkw, 
                                               spec.defaults, spec.kwonlyargs, 
                                               spec.kwonlydefaults, spec.annotations)
                return func_has_type(new_spec, ty)
            else: return True
        elif callable(val):
            return True # No clue
        else: return False
    elif isinstance(ty, List):
        return (isinstance(val, list))
# and \
#            all(map(lambda x: has_type_depth(x, ty.type, depth+1), val))
    elif isinstance(ty, Set):
        return isinstance(val, set) and \
            all(map(lambda x: has_type_depth(x, ty.type, depth+1), val))
    elif isinstance(ty, Dict):
        return isinstance(val, dict)# and \
#            all(map(lambda x: has_type_depth(x, ty.keys, depth+1), val.keys())) and \
#            all(map(lambda x: has_type_depth(x, ty.values, depth+1), val.values()))
    elif isinstance(ty, Tuple):
        return (isinstance(val, tuple) or isinstance(val, list))# \
#            and len(ty.elements) == len(val) and \
#            all(map(lambda p: has_type_depth(p[0], p[1], depth+1), zip(val, ty.elements)))
    # elif isinstance(ty, Iterable):
    #     if (isinstance(val, tuple) or isinstance(val, list) or isinstance(val, set)) or iter(val) is not val:
    #         return all(map(lambda x: has_type_depth(x, ty.type, depth+1), val))
    #     elif isinstance(val, collections.Iterable):
    #         if hasattr(val, '__iter__'):
    #             return has_type_depth(val.__iter__, Function([Dyn], Iterable(ty.type)), depth+1)
    #         else: return True
    #     else: return False
    elif isinstance(ty, Object):
        for k in ty.members:
            if not hasattr(val, k):# or not has_type_depth(getattr(val, k), ty.members[k], depth+1):
                return False
        return True
    elif isinstance(ty, Class):
        for k in ty.members:
            if not hasattr(val, k):# or not has_type_depth(getattr(val, k), ty.members[k], depth+1):
                return False
        return isinstance(val, type)
    else: raise UnknownTypeError('Unknown type ', ty)
Ejemplo n.º 17
0
def custom_getfullargspec(func):
    """Taken from CPython inspect.getfullargspec:
    The method is deprecated and uses

    skip_bound_args=False
    and follow_wrapped_chains=False
    because it was legacy behavior

    We need the opposite to follow the wrapped methods, and skip the bound arguments
    instead of manually removing them
  """

    try:
        sig = inspect._signature_from_callable(func,
                                               skip_bound_arg=True,
                                               follow_wrapper_chains=True,
                                               sigcls=inspect.Signature)
    except Exception as ex:
        # 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 inspect._POSITIONAL_ONLY:
            args.append(name)
        elif kind is inspect._POSITIONAL_OR_KEYWORD:
            args.append(name)
            if param.default is not param.empty:
                defaults += (param.default, )
        elif kind is inspect._VAR_POSITIONAL:
            varargs = name
        elif kind is inspect._KEYWORD_ONLY:
            kwonlyargs.append(name)
            if param.default is not param.empty:
                kwdefaults[name] = param.default
        elif kind is inspect._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 inspect.FullArgSpec(args, varargs, varkw, defaults, kwonlyargs,
                               kwdefaults, annotations)
Ejemplo n.º 18
0
    def test_basic_constructor_repr_cls_decorator(
        self, registry: _RegistryType
    ):
        @registry.mapped_as_dataclass()
        class A:
            __tablename__ = "a"

            id: Mapped[int] = mapped_column(primary_key=True, init=False)
            data: Mapped[str]

            x: Mapped[Optional[int]] = mapped_column(default=None)

            bs: Mapped[List["B"]] = relationship(  # noqa: F821
                default_factory=list
            )

        @registry.mapped_as_dataclass()
        class B:
            __tablename__ = "b"

            id: Mapped[int] = mapped_column(primary_key=True, init=False)
            a_id = mapped_column(ForeignKey("a.id"), init=False)
            data: Mapped[str]
            x: Mapped[Optional[int]] = mapped_column(default=None)

        A.__qualname__ = "some_module.A"
        B.__qualname__ = "some_module.B"

        eq_(
            pyinspect.getfullargspec(A.__init__),
            pyinspect.FullArgSpec(
                args=["self", "data", "x", "bs"],
                varargs=None,
                varkw=None,
                defaults=(None, mock.ANY),
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )
        eq_(
            pyinspect.getfullargspec(B.__init__),
            pyinspect.FullArgSpec(
                args=["self", "data", "x"],
                varargs=None,
                varkw=None,
                defaults=(None,),
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )

        a2 = A("10", x=5, bs=[B("data1"), B("data2", x=12)])

        # note a_id isn't included because it wasn't annotated
        eq_(
            repr(a2),
            "some_module.A(id=None, data='10', x=5, "
            "bs=[some_module.B(id=None, data='data1', x=None), "
            "some_module.B(id=None, data='data2', x=12)])",
        )

        a3 = A("data")
        eq_(repr(a3), "some_module.A(id=None, data='data', x=None, bs=[])")
Ejemplo n.º 19
0
    def test_integrated_dc(self, dc_decl_base: Type[MappedAsDataclass]):
        """We will be telling users "this is a dataclass that is also
        mapped". Therefore, they will want *any* kind of attribute to do what
        it would normally do in a dataclass, including normal types without any
        field and explicit use of dataclasses.field(). additionally, we'd like
        ``Mapped`` to mean "persist this attribute". So the absence of
        ``Mapped`` should also mean something too.

        """

        class A(dc_decl_base):
            __tablename__ = "a"

            ctrl_one: str = dataclasses.field()

            id: Mapped[int] = mapped_column(primary_key=True, init=False)
            data: Mapped[str]
            some_field: int = dataclasses.field(default=5)

            some_none_field: Optional[str] = dataclasses.field(default=None)

            some_other_int_field: int = 10

        # some field is part of the constructor
        a1 = A("ctrlone", "datafield")
        eq_(
            dataclasses.asdict(a1),
            {
                "ctrl_one": "ctrlone",
                "data": "datafield",
                "id": None,
                "some_field": 5,
                "some_none_field": None,
                "some_other_int_field": 10,
            },
        )

        a2 = A(
            "ctrlone",
            "datafield",
            some_field=7,
            some_other_int_field=12,
            some_none_field="x",
        )
        eq_(
            dataclasses.asdict(a2),
            {
                "ctrl_one": "ctrlone",
                "data": "datafield",
                "id": None,
                "some_field": 7,
                "some_none_field": "x",
                "some_other_int_field": 12,
            },
        )

        # only Mapped[] is mapped
        self.assert_compile(select(A), "SELECT a.id, a.data FROM a")
        eq_(
            pyinspect.getfullargspec(A.__init__),
            pyinspect.FullArgSpec(
                args=[
                    "self",
                    "ctrl_one",
                    "data",
                    "some_field",
                    "some_none_field",
                    "some_other_int_field",
                ],
                varargs=None,
                varkw=None,
                defaults=(5, None, 10),
                kwonlyargs=[],
                kwonlydefaults=None,
                annotations={},
            ),
        )
Ejemplo n.º 20
0
def Py3GetFullArgSpec(fn):
    """A alternative to the builtin getfullargspec.

  The builtin inspect.getfullargspec uses:
  `skip_bound_args=False, follow_wrapped_chains=False`
  in order to be backwards compatible.

  This function instead skips bound args (self) and follows wrapped chains.

  Args:
    fn: The function or class of interest.
  Returns:
    An inspect.FullArgSpec namedtuple with the full arg spec of the function.
  """
    # pylint: disable=no-member
    # pytype: disable=module-attr
    try:
        sig = inspect._signature_from_callable(  # pylint: disable=protected-access
            fn,
            skip_bound_arg=True,
            follow_wrapper_chains=True,
            sigcls=inspect.Signature)
    except Exception:
        # 'signature' can raise ValueError (most common), AttributeError, and
        # possibly others. We catch all exceptions here, and reraise a TypeError.
        raise TypeError('Unsupported callable.')

    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

        # pylint: disable=protected-access
        if kind is inspect._POSITIONAL_ONLY:
            args.append(name)
        elif kind is inspect._POSITIONAL_OR_KEYWORD:
            args.append(name)
            if param.default is not param.empty:
                defaults += (param.default, )
        elif kind is inspect._VAR_POSITIONAL:
            varargs = name
        elif kind is inspect._KEYWORD_ONLY:
            kwonlyargs.append(name)
            if param.default is not param.empty:
                kwdefaults[name] = param.default
        elif kind is inspect._VAR_KEYWORD:
            varkw = name
        if param.annotation is not param.empty:
            annotations[name] = param.annotation
        # pylint: enable=protected-access

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

    if not defaults:
        # compatibility with 'func.__defaults__'
        defaults = None
    return inspect.FullArgSpec(args, varargs, varkw, defaults, kwonlyargs,
                               kwdefaults, annotations)