Example #1
0
    def test_basics(self):
        class Node(Generic[T]):
            def __init__(self, label: T):
                self.label = label
                self.left = self.right = None

            def add_both(self, left: "Optional[Node[T]]", right: "Node[T]" = None, stuff: int = None, blah=None):
                self.left = left
                self.right = right

            def add_left(self, node: Optional["Node[T]"]):
                self.add_both(node, None)

            def add_right(self, node: "Node[T]" = None):
                self.add_both(None, node)

        t = Node[int]
        both_hints = get_type_hints(t.add_both, globals(), locals())
        self.assertEqual(both_hints["left"], Optional[Node[T]])
        self.assertEqual(both_hints["right"], Optional[Node[T]])
        self.assertEqual(both_hints["left"], both_hints["right"])
        self.assertEqual(both_hints["stuff"], Optional[int])
        self.assertNotIn("blah", both_hints)

        left_hints = get_type_hints(t.add_left, globals(), locals())
        self.assertEqual(left_hints["node"], Optional[Node[T]])

        right_hints = get_type_hints(t.add_right, globals(), locals())
        self.assertEqual(right_hints["node"], Optional[Node[T]])
Example #2
0
    def test_basics(self):

        class Node(Generic[T]):

            def __init__(self, label: T):
                self.label = label
                self.left = self.right = None

            def add_both(self,
                         left: 'Optional[Node[T]]',
                         right: 'Node[T]' = None,
                         stuff: int = None,
                         blah=None):
                self.left = left
                self.right = right

            def add_left(self, node: Optional['Node[T]']):
                self.add_both(node, None)

            def add_right(self, node: 'Node[T]' = None):
                self.add_both(None, node)

        t = Node[int]
        both_hints = get_type_hints(t.add_both, globals(), locals())
        self.assertEqual(both_hints['left'], Optional[Node[T]])
        self.assertEqual(both_hints['right'], Optional[Node[T]])
        self.assertEqual(both_hints['left'], both_hints['right'])
        self.assertEqual(both_hints['stuff'], Optional[int])
        self.assertNotIn('blah', both_hints)

        left_hints = get_type_hints(t.add_left, globals(), locals())
        self.assertEqual(left_hints['node'], Optional[Node[T]])

        right_hints = get_type_hints(t.add_right, globals(), locals())
        self.assertEqual(right_hints['node'], Optional[Node[T]])
Example #3
0
    def test_delayed_syntax_error(self):

        def foo(a: 'Node[T'):
            pass

        with self.assertRaises(SyntaxError):
            get_type_hints(foo)
Example #4
0
    def test_basics(self):

        class Node(Generic[T]):

            def __init__(self, label: T):
                self.label = label
                self.left = self.right = None

            def add_both(self,
                         left: 'Optional[Node[T]]',
                         right: 'Node[T]' = None,
                         stuff: int = None,
                         blah=None):
                self.left = left
                self.right = right

            def add_left(self, node: Optional['Node[T]']):
                self.add_both(node, None)

            def add_right(self, node: 'Node[T]' = None):
                self.add_both(None, node)

        t = Node[int]
        both_hints = get_type_hints(t.add_both, globals(), locals())
        assert both_hints['left'] == both_hints['right'] == Optional[Node[T]]
        assert both_hints['stuff'] == Optional[int]
        assert 'blah' not in both_hints

        left_hints = get_type_hints(t.add_left, globals(), locals())
        assert left_hints['node'] == Optional[Node[T]]

        right_hints = get_type_hints(t.add_right, globals(), locals())
        assert right_hints['node'] == Optional[Node[T]]
Example #5
0
    def test_name_error(self):

        def foo(a: 'Noode[T]'):
            pass

        with self.assertRaises(NameError):
            get_type_hints(foo, locals())
Example #6
0
    def test_type_error(self):

        def foo(a: Tuple['42']):
            pass

        with self.assertRaises(TypeError):
            get_type_hints(foo)
Example #7
0
    def test_basics(self):
        class Node(Generic[T]):
            def __init__(self, label: T):
                self.label = label
                self.left = self.right = None

            def add_both(self, left: "Optional[Node[T]]", right: "Node[T]" = None, stuff: int = None, blah=None):
                self.left = left
                self.right = right

            def add_left(self, node: Optional["Node[T]"]):
                self.add_both(node, None)

            def add_right(self, node: "Node[T]" = None):
                self.add_both(None, node)

        t = Node[int]
        both_hints = get_type_hints(t.add_both, globals(), locals())
        assert both_hints["left"] == both_hints["right"] == Optional[Node[T]]
        assert both_hints["stuff"] == Optional[int]
        assert "blah" not in both_hints

        left_hints = get_type_hints(t.add_left, globals(), locals())
        assert left_hints["node"] == Optional[Node[T]]

        right_hints = get_type_hints(t.add_right, globals(), locals())
        assert right_hints["node"] == Optional[Node[T]]
Example #8
0
    def test_generics_replacement(self):
        """
        Most basic change. Confirm that generic parameters are actually swapped
        out on child classes.
        """
        Domain = hktyping.HKTypeVar('Domain')
        Codomain = hktyping.HKTypeVar('Codomain')

        class Functor(hktyping.HKGeneric[Domain, Codomain]):
            def fmap_like(self, function: Domain) -> Codomain:
                pass
        class ListFunctor(Functor[AnyCategory, ListCategory]):
            pass
        listf = ListFunctor()

        self.assertEqual(Functor.__parameters__, (Domain, Codomain))
        self.assertEqual(ListFunctor.__parameters__, (AnyCategory, ListCategory))
        self.assertEqual(listf.__parameters__, (AnyCategory, ListCategory))

        #
        #  THIS IS BAD - AND I SHOULD FEEL BAD
        #   It looks like the replacement is occuring to the parent, which is terrible
        #
        self.assertNotEqual(
            typing.get_type_hints(Functor.fmap_like),
            {'function': Domain, 'return': Codomain})
        # These are correct
        self.assertEqual(
            typing.get_type_hints(ListFunctor.fmap_like),
            {'function': AnyCategory, 'return': ListCategory})
        self.assertEqual(
            typing.get_type_hints(listf.fmap_like),
            {'function': AnyCategory, 'return': ListCategory})
Example #9
0
    def test_standard_generics(self):
        Domain = typing.TypeVar('Domain')
        Codomain = typing.TypeVar('Codomain')

        class Functor(typing.Generic[Domain, Codomain]):
            def fmap_like(self, function: Domain) -> Codomain:
                pass
        class ListFunctor(Functor[AnyCategory, ListCategory]):
            pass
        listf = ListFunctor()

        self.assertEqual(Functor.__parameters__, (Domain, Codomain))
        self.assertEqual(ListFunctor.__parameters__, (AnyCategory, ListCategory))
        self.assertEqual(listf.__parameters__, (AnyCategory, ListCategory))


        self.assertEqual(
            typing.get_type_hints(Functor.fmap_like),
            {'function': Domain, 'return': Codomain})
        # This is bad behavior - the __annotations__ on methods on our child class & instances
        #   does not reflect the changes to __parameters__
        #   However, this is the default behavior of typing, so I'm testing for it
        self.assertEqual(
            typing.get_type_hints(ListFunctor.fmap_like),
            {'function': Domain, 'return': Codomain})
        self.assertEqual(
            typing.get_type_hints(listf.fmap_like),
            {'function': Domain, 'return': Codomain})
Example #10
0
    def test_no_type_check_class(self):
        @no_type_check
        class C:
            def foo(a: "whatevers") -> {}:
                pass

        cth = get_type_hints(C.foo)
        self.assertEqual(cth, {})
        ith = get_type_hints(C().foo)
        self.assertEqual(ith, {})
Example #11
0
def generate_new_enforcer(func, generic, parent_root, instance_of, settings):
    """
    Private function for generating new Enforcer instances for the incoming function
    """
    if parent_root is not None:
        if type(parent_root) is not Validator:
            raise TypeError('Parent validator must be a Validator')

    if instance_of is not None:
        if type(instance_of) is not GenericProxy:
            raise TypeError('Instance of a generic must be derived from a valid Generic Proxy')

    if generic:
        hints = OrderedDict()

        if instance_of:
            func = instance_of

        func_type = type(func)

        has_origin = func.__origin__ is not None

        # Collects generic's parameters - TypeVar-s specified on itself or on origin (if constrained)
        if not func.__parameters__ and (not has_origin or not func.__origin__.__parameters__):
            raise TypeError('User defined generic is invalid')

        parameters = func.__parameters__ if func.__parameters__ else func.__origin__.__parameters__

        # Maps parameter names to parameters, while preserving the order of their definition
        for param in parameters:
            hints[param.__name__] = EnhancedTypeVar(param.__name__, type_var=param)

        # Verifies that constraints do not contradict generic's parameter definition
        # and bounds parameters to constraints (if constrained)
        bound = bool(func.__args__)
        if bound:
            for i, param in enumerate(hints.values()):
                arg = func.__args__[i]
                if is_type_of_type(arg, param):
                    param.__bound__ = arg
                else:
                    raise TypeError('User defined generic does not accept provided constraints')

        # NOTE:
        # Signature in generics should always point to the original unconstrained generic
        # This applies even to the instances of such Generics

        if has_origin:
            signature = func.__origin__
        else:
            signature = func.__wrapped__ if func_type is GenericProxy else func

        validator = init_validator(hints, parent_root)
    else:
        bound = False
        signature = inspect.signature(func)
        hints = typing.get_type_hints(func)
        validator = init_validator(hints, parent_root)

    return Enforcer(validator, signature, hints, generic, bound, settings)
Example #12
0
    def fields(self) -> Dict[str, _Field]:
        def make_factory(value: object) -> Callable[[], Any]:
            return lambda: value

        if self._fields is None:
            hints = typing.get_type_hints(self.type)
            # This is gnarly. Sorry. For each field, store its default_factory if present; otherwise
            # create a factory returning its default if present; otherwise None. Default parameter
            # in the lambda is a ~~hack~~ to avoid messing up the variable binding.
            fields: Dict[str, _Field] = {
                field.name: _Field(
                    field.default_factory  # type: ignore
                    if field.default_factory is not MISSING  # type: ignore
                    else (
                        (make_factory(field.default))
                        if field.default is not MISSING
                        else None
                    ),
                    hints[field.name],
                )
                for field in dataclasses.fields(self.type)
            }

            self._fields = fields

        return self._fields
Example #13
0
    def test_get_type_hints_dummy(self):

        def foo(x):
            # type: (int) -> int
            return x + 1

        self.assertIsNone(typing.get_type_hints(foo))
Example #14
0
    def register(cls, func=None):
        """generic_func.register(cls, func) -> func

        Registers a new implementation for the given *cls* on a *generic_func*.

        """
        nonlocal cache_token
        if func is None:
            if isinstance(cls, type):
                return lambda f: register(cls, f)
            ann = getattr(cls, '__annotations__', {})
            if not ann:
                raise TypeError(
                    f"Invalid first argument to `register()`: {cls!r}. "
                    f"Use either `@register(some_class)` or plain `@register` "
                    f"on an annotated function."
                )
            func = cls

            # only import typing if annotation parsing is necessary
            from typing import get_type_hints
            argname, cls = next(iter(get_type_hints(func).items()))
            assert isinstance(cls, type), (
                f"Invalid annotation for {argname!r}. {cls!r} is not a class."
            )
        registry[cls] = func
        if cache_token is None and hasattr(cls, '__abstractmethods__'):
            cache_token = get_cache_token()
        dispatch_cache.clear()
        return func
Example #15
0
def polymorphic(func):
    global _registry
    func_key = func.__module__ + '.' + func.__qualname__
    parameters = signature(func).parameters
    parameters_tuple = tuple(parameters.values())
    if func_key not in _registry:
        def dispatcher(*args, **kwargs):
            return _call_func(func_key, args, kwargs)
        dispatcher = update_dispatcher(dispatcher, func, assign=True)
        signature_mapping = OrderedDict()
        signature_mapping[parameters_tuple] = func
        signature_mapping.dispatcher = dispatcher
        _registry[func_key] = signature_mapping
        return dispatcher
    elif parameters_tuple not in _registry[func_key]:
        _registry[func_key][parameters_tuple] = func
        dispatcher = _registry[func_key].dispatcher
        return update_dispatcher(dispatcher, func, assign=False)
    else:
        hints = get_type_hints(func)
        sig_gen = (
            '{}:{}'.format(p, hints[p]) if p in hints else p
            for p in parameters
        )
        raise PolypieException(
            "Function '{func}' with signature ({sig}) "
            "already exists".format(func=func_key, sig=', '.join(sig_gen))
        )
def wrap_fun(fun: T, injector: Injector) -> T:
    if isinstance(fun, LocalProxy):
        return fun  # type: ignore

    if ismethod(fun):
        fun = instance_method_wrapper(fun)

    # Important: this block needs to stay here so it's executed *before* the
    # hasattr(fun, '__call__') block below - otherwise things may crash.
    if hasattr(fun, '__bindings__'):
        return wrap_function(fun, injector)

    if hasattr(fun, '__call__') and not isinstance(fun, type):
        try:
            type_hints = get_type_hints(fun)
        except (AttributeError, TypeError):
            # Some callables aren't introspectable with get_type_hints,
            # let's assume they don't have anything to inject. The exception
            # types handled here are what I encountered so far.
            # It used to be AttributeError, then https://github.com/python/typing/pull/314
            # changed it to TypeError.
            wrap_it = False
        except NameError:
            wrap_it = True
        else:
            type_hints.pop('return', None)
            wrap_it = type_hints != {}
        if wrap_it:
            return wrap_fun(inject(fun), injector)

    if hasattr(fun, 'view_class'):
        return wrap_class_based_view(fun, injector)

    return fun
def annotations_corrector(cls, method_name):
    """
    Now... how to make this replace the __annotations__? Options
    (1) Look in the internals of typing.py
    (2) Run/replace on classes after construction
    (3) Somehow turn __annotations__ into a getter

    """
    method = getattr(cls, method_name)
    annotations = typing.get_type_hints(method)
    
    accumulator = dict()
    for key, value in annotations.items():
        # If it is an unfilled typevar
        if isinstance(value, typing.TypeVar):
            # Find parent with generic version of this parameter
            position = None
            for parent in cls.__mro__:
                if value in getattr(parent, '__parameters__', []):
                    position = parent.__parameters__.index(value)

            if position is None:
                raise ValueError("Could not find position in __parameters__ of parent classes")

            concrete = cls.__parameters__[position]
            accumulator[key] = concrete
        else:
            accumulator[key] = value

    return accumulator
Example #18
0
    def test_no_type_check(self):
        @no_type_check
        def foo(a: "whatevers") -> {}:
            pass

        th = get_type_hints(foo)
        self.assertEqual(th, {})
Example #19
0
def message(cls: Type[T]) -> Type[T]:
    """
    Returns the same class as was passed in, with additional dunder attributes needed for
    serialization and deserialization.
    """

    type_hints = get_type_hints(cls)

    try:
        # Used to list all fields and locate fields by field number.
        cls.__protobuf_fields__: Dict[int, Field] = dict(
            make_field(field_.metadata['number'], field_.name, type_hints[field_.name])
            for field_ in dataclasses.fields(cls)
        )
    except KeyError as e:
        # FIXME: catch `KeyError` in `make_field` and re-raise as `TypeError`.
        raise TypeError(f'type is not serializable: {e}') from e

    # noinspection PyUnresolvedReferences
    Message.register(cls)
    cls.serializer = MessageSerializer(cls)
    cls.type_url = f'type.googleapis.com/{cls.__module__}.{cls.__name__}'
    cls.validate = Message.validate
    cls.dump = Message.dump
    cls.dumps = Message.dumps
    cls.merge_from = Message.merge_from
    cls.load = classmethod(load)
    cls.loads = classmethod(loads)

    return cls
Example #20
0
def delgator(pol_tr: PolTRSpec, method: typing.Callable):
    """
    Helper function to delegate methods calls from PolTRSpec to
    the methods of TimeResSpec.

    Parameters
    ----------
    pol_tr : PolTRSpec
    method : method of TimeResSpec
        The method to wrap. Uses function annotations to check if the
        method returns a new TimeResSpec.
    """
    name = method.__name__
    hints = typing.get_type_hints(method)
    if "return" in hints:
        do_return = hints["return"] == TimeResSpec
    else:
        do_return = False

    @functools.wraps(method)
    def func(*args, **kwargs):
        para = method(pol_tr.para, *args, **kwargs)
        perp = method(pol_tr.perp, *args, **kwargs)
        if do_return:
            return PolTRSpec(para, perp)

    func.__docs__ = method.__doc__
    func.__name__ = name
    return func
Example #21
0
def check_callable(callable_: typing.Callable, hint: type) -> bool:
    """Check argument type & return type of :class:`typing.Callable`. since it
    raises check :class:`typing.Callable` using `isinstance`, so compare in
    diffrent way

    :param callable_: callable object given as a argument
    :param hint: assumed type of given ``callable_``

    """
    if not callable(callable_):
        return type(callable_), False
    if callable(callable_) and not hasattr(callable_, '__code__'):
        return type(callable_), True
    hints = typing.get_type_hints(callable_)
    return_type = hints.pop('return', type(None))
    signature = inspect.signature(callable_)
    arg_types = tuple(
        param.annotation
        for _, param in signature.parameters.items()
    )
    correct = all({
        any({
            hint.__args__ is None,
            hint.__args__ is Ellipsis,
            hint.__args__ == arg_types,
        }),
        any({
            hint.__result__ is None,
            hint.__result__ in (typing.Any, return_type)
        })
    })
    return typing.Callable[list(arg_types), return_type], correct
Example #22
0
def get_signature(func):
    """
    Gathers information about the call signature of `func`.
    """
    code = func.__code__

    # Names of regular parameters
    parameters = tuple(code.co_varnames[:code.co_argcount])

    # Flags
    has_varargs = bool(code.co_flags & inspect.CO_VARARGS)
    has_varkw = bool(code.co_flags & inspect.CO_VARKEYWORDS)
    has_kwonly = bool(code.co_kwonlyargcount)

    # A mapping of parameter names to default values
    default_values = func.__defaults__ or ()
    defaults = dict(zip(parameters[-len(default_values):], default_values))

    # Type annotations for all parameters
    type_hints = typing.get_type_hints(func) if typing else func.__annotations__
    types = tuple(normalize_type(type_hints.get(param, AnyType)) for param in parameters)

    # Type annotations for required parameters
    required = types[:-len(defaults)] if defaults else types

    # Complexity
    complexity = tuple(map(type_complexity, types)) if typing else None

    return Signature(parameters, types, complexity, defaults, required,
                     has_varargs, has_varkw, has_kwonly)
def _annotations_corrector(function, bases, parameters):
    """
    """
    annotations = typing.get_type_hints(function)    
    accumulator = dict()
    for key, value in annotations.items():
        # If it is an unfilled typevar
        if isinstance(value, typing.TypeVar):
            # Find parent with generic version of this parameter
            position = None
            for parent in bases:
                if value in getattr(parent, '__parameters__', []):
                    position = parent.__parameters__.index(value)
            if position is None:
                raise ValueError("Could not find position in __parameters__ of parent classes")

            # If this is a structured reference, resolve it
            if _is_structured_forward_ref(value):
                base = parameters[position]
                tinyns = {value._structured_forward_ref_name: parameters[position]}
                # my_lambda = "lambda {0}: {1}".format(value._structured_forward_ref_name, value._structured_forward_ref_code)
                concrete = eval(value._structured_forward_ref_code, tinyns)                
            else:
                concrete = parameters[position]

            accumulator[key] = concrete
        else:
            accumulator[key] = value
    return accumulator
Example #24
0
    def test_callable_with_ellipsis_forward(self):

        def foo(a: 'Callable[..., T]'):
            pass

        self.assertEqual(get_type_hints(foo, globals(), locals()),
                         {'a': Callable[..., T]})
Example #25
0
    def test_union_forward(self):

        def foo(a: Union['T']):
            pass

        self.assertEqual(get_type_hints(foo, globals(), locals()),
                         {'a': Union[T]})
Example #26
0
    def test_tuple_forward(self):

        def foo(a: Tuple['T']):
            pass

        self.assertEqual(get_type_hints(foo, globals(), locals()),
                         {'a': Tuple[T]})
Example #27
0
    def test_callable_forward(self):

        def foo(a: Callable[['T'], 'T']):
            pass

        self.assertEqual(get_type_hints(foo, globals(), locals()),
                         {'a': Callable[[T], T]})
Example #28
0
    def type_check(item, attr_name, value):
        th_cls = typing.get_type_hints(item) if hasattr(item, '__annotations__') else {}
        try:
            tt = th_cls[attr_name]
        except KeyError:
            th_init = typing.get_type_hints(item.__init__)
            try:
                tt = th_init[attr_name]
            except KeyError:
                return

        allowed = typing_inspect.get_args(tt) or tt
        if not isinstance(value, allowed):
            one_of = "with one of following types" if isinstance(allowed, tuple) else "of type"
            return "Expected value {one_of}: {exp}, got {got} for {cls}.{member}".format(
                one_of=one_of, exp=allowed, got=type(value), cls=item.__class__.__name__, member=attr_name)

        return None
Example #29
0
def get_output_interface(func):
    return_type = get_type_hints(func).get('return')
    if return_type is None:
        return None
    # Unwrap iterators (used for geom shader output)
    origin = getattr(return_type, '__origin__', None)
    if origin is not None and origin == Iterator:
        return_type = return_type.__parameters__[0]
    return return_type
Example #30
0
 def test_default_globals(self):
     code = ("class C:\n"
             "    def foo(self, a: 'C') -> 'D': pass\n"
             "class D:\n"
             "    def bar(self, b: 'D') -> C: pass\n"
             )
     ns = {}
     exec(code, ns)
     hints = get_type_hints(ns['C'].foo)
     assert hints == {'a': ns['C'], 'return': ns['D']}
Example #31
0
    def test_tuple_forward(self):

        def foo(a: Tuple['T']):
            pass

        self.assertEqual(get_type_hints(foo), {'a': Tuple[T]})
Example #32
0
 def test_typing_present(self):
     assert is_palindromic.__hints__ == typing.get_type_hints(self.is_palindromic_oracle)
     assert typing.get_type_hints (gen_palindromic) == typing.get_type_hints (self.gen_palindromic_oracle)
     assert typing.get_type_hints (represent) == typing.get_type_hints (self.represent_oracle)
Example #33
0
    def test_callable_forward(self):

        def foo(a: Callable[['T'], 'T']):
            pass

        self.assertEqual(get_type_hints(foo), {'a': Callable[[T], T]})
Example #34
0
def test_slot_add_returntype():
    def test(self, name: str) -> str:
        ...

    slot_kwargs = utils._slot_kwargs(get_type_hints(test))
    assert slot_kwargs == {"result": str}
Example #35
0
 def __init__(self, dto_obj: dto.ReportItemMessageDto) -> None:
     super().__init__(dto_obj)
     self._obj = get_type_hints(self.__class__).get("_obj")(  # type: ignore
         **dto_obj.payload)
Example #36
0
 def get_type_hints(thing):
     try:
         import typing
         return typing.get_type_hints(thing)
     except TypeError:
         return {}
Example #37
0
 def generate_inputs(cls):
     return {
         name: generate_for_type(typ)
         for name, typ in get_type_hints(cls.solution).items()
     }
Example #38
0
 def _fields(cls) -> dict[str, type]:
     return {
         name: py_type
         for name, py_type in get_type_hints(cls).items()
         if not name.startswith('_')
     }
def formatargspec(function, args, varargs=None, varkw=None, defaults=None,
                  kwonlyargs=(), kwonlydefaults={}, annotations={}):
    # type: (Callable, Tuple[str, ...], str, str, Any, Tuple, Dict, Dict[str, Any]) -> str
    """Return a string representation of an ``inspect.FullArgSpec`` tuple.

    An enhanced version of ``inspect.formatargspec()`` that handles typing
    annotations better.
    """
    warnings.warn('formatargspec() is now deprecated.  '
                  'Please use sphinx.util.inspect.Signature instead.',
                  RemovedInSphinx20Warning)

    def format_arg_with_annotation(name):
        # type: (str) -> str
        if name in annotations:
            return '%s: %s' % (name, format_annotation(get_annotation(name)))
        return name

    def get_annotation(name):
        # type: (str) -> str
        value = annotations[name]
        if isinstance(value, string_types):
            return introspected_hints.get(name, value)
        else:
            return value

    introspected_hints = (typing.get_type_hints(function)  # type: ignore
                          if typing and hasattr(function, '__code__') else {})

    fd = StringIO()
    fd.write('(')

    formatted = []
    defaults_start = len(args) - len(defaults) if defaults else len(args)

    for i, arg in enumerate(args):
        arg_fd = StringIO()
        if isinstance(arg, list):
            # support tupled arguments list (only for py2): def foo((x, y))
            arg_fd.write('(')
            arg_fd.write(format_arg_with_annotation(arg[0]))
            for param in arg[1:]:
                arg_fd.write(', ')
                arg_fd.write(format_arg_with_annotation(param))
            arg_fd.write(')')
        else:
            arg_fd.write(format_arg_with_annotation(arg))
            if defaults and i >= defaults_start:
                arg_fd.write(' = ' if arg in annotations else '=')
                arg_fd.write(object_description(defaults[i - defaults_start]))  # type: ignore
        formatted.append(arg_fd.getvalue())

    if varargs:
        formatted.append('*' + format_arg_with_annotation(varargs))

    if kwonlyargs:
        if not varargs:
            formatted.append('*')

        for kwarg in kwonlyargs:
            arg_fd = StringIO()
            arg_fd.write(format_arg_with_annotation(kwarg))
            if kwonlydefaults and kwarg in kwonlydefaults:
                arg_fd.write(' = ' if kwarg in annotations else '=')
                arg_fd.write(object_description(kwonlydefaults[kwarg]))  # type: ignore
            formatted.append(arg_fd.getvalue())

    if varkw:
        formatted.append('**' + format_arg_with_annotation(varkw))

    fd.write(', '.join(formatted))
    fd.write(')')

    if 'return' in annotations:
        fd.write(' -> ')
        fd.write(format_annotation(get_annotation('return')))

    return fd.getvalue()
Example #40
0
 def test_typing_present(self):
     assert list_filter.__hints__ == typing.get_type_hints(
         self.list_filter_oracle)
Example #41
0
        比较简单, 需要先了解 typing 这个库
        :param a:
        :param b:
        :param c:
        :return:
        """
        pass


XX = type('XX', (object, ), dict(a=1))  # 产生一个新的类型 XX
print('------X和XX')
print(X)
print(XX)
# <class '__main__.X'>
# <class '__main__.X'>
print('类型------X和XX类')
print(type(X))
print(type(XX))
print('类型------实例化X和XX')
print(type(X()))
print(type(XX()))


# type hint
def type_func(param: str) -> str:
    pass


print(typing.get_type_hints(X))
print(typing.get_type_hints(type_func))
Example #42
0
    "elements": ["Si", "O"],
    "exclude_elements": ["Si"],
    "possible_species": ["O2-"],
    "crystal_system": CrystalSystem.cubic,
    "spacegroup_number": 38,
    "spacegroup_symbol": "Amm2",
    "has_props": [HasProps.dielectric],
    "theoretical": True,
    "has_reconstructed": False,
    "magnetic_ordering": Ordering.FM,
}  # type: dict

search_method = SummaryRester().search

# Get list of parameters
param_tuples = list(typing.get_type_hints(search_method).items())

# Query API for each numeric and boolean parameter and check if returned
for entry in param_tuples:
    param = entry[0]
    if param not in excluded_params:
        param_type = entry[1].__args__[0]
        q = None

        if param in custom_field_tests:
            project_field = alt_name_dict.get(param, None)
            q = {
                param: custom_field_tests[param],
                "chunk_size": 1,
                "num_chunks": 1,
            }
Example #43
0
 def stream(self, f: BinaryIO) -> None:
     for f_name, f_type in get_type_hints(self).items():  # type: ignore
         self.stream_one_item(f_type, getattr(self, f_name), f)
Example #44
0
 def parse(cls: Type[cls.__name__],
           f: BinaryIO) -> cls.__name__:  # type: ignore
     values = []
     for _, f_type in get_type_hints(cls).items():
         values.append(cls.parse_one_item(f_type, f))  # type: ignore
     return cls(*values)
Example #45
0
    def test_union_forward(self):

        def foo(a: Union['T']):
            pass

        self.assertEqual(get_type_hints(foo), {'a': Union[T]})
Example #46
0
def iter_register_deps(cls):
    for value in typing.get_type_hints(cls, {}, {}).values():
        dependency = get_dependency_from_annotation(value)
        if dependency is not None:
            yield dependency
Example #47
0
def test_initialisation():
    class Original:
        a: str = "a_default"
        b: str = None
        c: str

    assert get_type_hints(Original) == {"a": str, "b": str, "c": str}
    assert Original.a == "a_default"
    assert Original.b is None
    assert not hasattr(Original, "c")

    DecoratedOriginal = envvar_profile_cls(Original)

    assert issubclass(DecoratedOriginal, EnvvarProfile)
    assert DecoratedOriginal.profile_root == "original"
    assert DecoratedOriginal.profile_properties == ["a", "b", "c"]
    assert DecoratedOriginal.a == EnvvarProfileProperty("a", "a_default", str)
    assert DecoratedOriginal.b == EnvvarProfileProperty("b", None, str)
    assert DecoratedOriginal.c == EnvvarProfileProperty("c", None, str)

    class Derived(DecoratedOriginal):
        b: str = "b_default"
        d: str = None
        e: str

    assert Derived.profile_properties == ["a", "b", "c"]
    assert Derived.b == "b_default"
    assert Derived.d is None
    assert not hasattr(Derived, "e")

    DecoratedDerived = envvar_profile_cls(Derived)
    assert DecoratedDerived.profile_root == "derived"
    assert DecoratedDerived.profile_properties == ["a", "b", "c", "d", "e"]

    assert DecoratedDerived.a == EnvvarProfileProperty("a", "a_default", str)
    assert DecoratedDerived.b == EnvvarProfileProperty("b", "b_default", str)
    assert DecoratedDerived.c == EnvvarProfileProperty("c", None, str)
    assert DecoratedDerived.d == EnvvarProfileProperty("d", None, str)
    assert DecoratedDerived.e == EnvvarProfileProperty("e", None, str)

    assert isinstance(DecoratedDerived.c, EnvvarProfileProperty)
    assert DecoratedDerived.c.name == "c"
    assert DecoratedDerived.c.default is None
    assert DecoratedDerived.c.type_ is str

    assert isinstance(DecoratedDerived.a, EnvvarProfileProperty)
    assert DecoratedDerived.a.name == "a"
    assert DecoratedDerived.a.default == "a_default"
    assert DecoratedDerived.a.type_ is str

    class DoubleDerived(DecoratedDerived):
        f: str = None

    assert DoubleDerived.profile_properties == ["a", "b", "c", "d", "e"]

    DecoratedDoubleDerived = envvar_profile_cls(DoubleDerived)
    assert DecoratedDoubleDerived.profile_root == "double_derived"
    assert DecoratedDoubleDerived.profile_properties == [
        "a", "b", "c", "d", "e", "f"
    ]

    assert DecoratedDoubleDerived.a == EnvvarProfileProperty(
        "a", "a_default", str)
    assert DecoratedDoubleDerived.b == EnvvarProfileProperty(
        "b", "b_default", str)
    assert DecoratedDoubleDerived.c == EnvvarProfileProperty("c", None, str)
    assert DecoratedDoubleDerived.d == EnvvarProfileProperty("d", None, str)
    assert DecoratedDoubleDerived.e == EnvvarProfileProperty("e", None, str)
    assert DecoratedDoubleDerived.f == EnvvarProfileProperty("f", None, str)
Example #48
0
 def test_typing_present(self):
     assert divisors.__hints__ == typing.get_type_hints(
         self.divisors_oracle)
Example #49
0
 def __set_name__(self, owner: Processor, name):
     types = typing.get_type_hints(self.fn)
     owner.handle_message.register(types['msg'], self.fn)
     setattr(owner, name, self.fn)
def return_type(func: FunctionType) -> str:
    value = get_type_hints(func, globals())["return"]
    return process_type(value)
Example #51
0
 def _get_needs_for_ctor(self, cls):
     try:
         return typing.get_type_hints(cls.__init__, None, self._localns)
     except NameError as e:
         raise InvalidForwardReferenceException(str(e))
    def serialize_python_type(self, value: Any) -> str:
        str_value = str(value)
        if isinstance(value, list):
            return f"[{', '.join(list(map(lambda a: self.serialize_python_type(a), value)))}]"
        if str_value == "<class 'playwright._impl._types.Error'>":
            return "Error"
        match = re.match(r"^<class '((?:pathlib\.)?\w+)'>$", str_value)
        if match:
            return match.group(1)
        match = re.match(
            r"playwright._impl._event_context_manager.EventContextManagerImpl\[playwright._impl.[^.]+.(.*)\]",
            str_value,
        )
        if match:
            return "EventContextManager[" + match.group(1) + "]"
        match = re.match(r"^<class 'playwright\._impl\.[\w_]+\.([^']+)'>$",
                         str_value)
        if (match and "_api_structures" not in str_value
                and "_api_types" not in str_value):
            if match.group(1) == "EventContextManagerImpl":
                return "EventContextManager"
            return match.group(1)

        match = re.match(r"^typing\.(\w+)$", str_value)
        if match:
            return match.group(1)

        origin = get_origin(value)
        args = get_args(value)
        hints = None
        try:
            hints = get_type_hints(value)
        except Exception:
            pass
        if hints:
            signature: List[str] = []
            for [name, value] in hints.items():
                signature.append(
                    f"{name}: {self.serialize_python_type(value)}")
            return f"{{{', '.join(signature)}}}"
        if origin == Union:
            args = get_args(value)
            if len(args) == 2 and str(args[1]) == "<class 'NoneType'>":
                return self.make_optional(self.serialize_python_type(args[0]))
            ll = list(map(lambda a: self.serialize_python_type(a), args))
            ll.sort(key=lambda item: "}" if item == "NoneType" else item)
            return f"Union[{', '.join(ll)}]"
        if str(origin) == "<class 'dict'>":
            args = get_args(value)
            return f"Dict[{', '.join(list(map(lambda a: self.serialize_python_type(a), args)))}]"
        if str(origin) == "<class 'list'>":
            args = get_args(value)
            return f"List[{', '.join(list(map(lambda a: self.serialize_python_type(a), args)))}]"
        if str(origin) == "<class 'collections.abc.Callable'>":
            args = get_args(value)
            return f"Callable[{', '.join(list(map(lambda a: self.serialize_python_type(a), args)))}]"
        if str(origin) == "typing.Literal":
            args = get_args(value)
            if len(args) == 1:
                return '"' + self.serialize_python_type(args[0]) + '"'
            body = ", ".join(
                list(
                    map(lambda a: '"' + self.serialize_python_type(a) + '"',
                        args)))
            return f"Union[{body}]"
        return str_value
Example #53
0
def test_slot_ignore_self():
    def test(self, name: str):
        ...

    slot_args = utils._slot_args(test, get_type_hints(test))
    assert slot_args == [str]
Example #54
0
    def __init__(self,
                 func: Callable,
                 frame_locals: Optional[Dict[str, Any]] = None,
                 args: tuple = None,
                 kwargs: Dict[str, Any] = None,
                 forward_refs_policy=ForwardRefPolicy.ERROR):
        super().__init__(func.__globals__, frame_locals)
        self.func = func
        self.func_name = function_name(func)
        self.is_generator = isgeneratorfunction(func)
        signature = inspect.signature(func)

        if args is not None and kwargs is not None:
            self.arguments = signature.bind(*args, **kwargs).arguments
        else:
            assert frame_locals is not None, 'frame must be specified if args or kwargs is None'
            self.arguments = frame_locals

        self.type_hints = _type_hints_map.get(func)
        if self.type_hints is None:
            while True:
                if sys.version_info < (3, 5, 3):
                    frame_locals = dict(frame_locals)

                try:
                    hints = get_type_hints(func, localns=frame_locals)
                except NameError as exc:
                    if forward_refs_policy is ForwardRefPolicy.ERROR:
                        raise

                    typename = str(exc).split("'", 2)[1]
                    for param in signature.parameters.values():
                        if param.annotation == typename:
                            break
                    else:
                        raise

                    func_name = function_name(func)
                    if forward_refs_policy is ForwardRefPolicy.GUESS:
                        if param.name in self.arguments:
                            argtype = self.arguments[param.name].__class__
                            if param.annotation == argtype.__qualname__:
                                func.__annotations__[param.name] = argtype
                                msg = (
                                    'Replaced forward declaration {!r} in {} with {!r}'
                                    .format(param.annotation, func_name,
                                            argtype))
                                warn(TypeHintWarning(msg))
                                continue

                    msg = 'Could not resolve type hint {!r} on {}: {}'.format(
                        param.annotation, function_name(func), exc)
                    warn(TypeHintWarning(msg))
                    del func.__annotations__[param.name]
                else:
                    break

            self.type_hints = OrderedDict()
            for name, parameter in signature.parameters.items():
                if name in hints:
                    annotated_type = hints[name]

                    # PEP 428 discourages it by MyPy does not complain
                    if parameter.default is None:
                        annotated_type = Optional[annotated_type]

                    if parameter.kind == Parameter.VAR_POSITIONAL:
                        self.type_hints[name] = Tuple[annotated_type, ...]
                    elif parameter.kind == Parameter.VAR_KEYWORD:
                        self.type_hints[name] = Dict[str, annotated_type]
                    else:
                        self.type_hints[name] = annotated_type

            if 'return' in hints:
                self.type_hints['return'] = hints['return']

            _type_hints_map[func] = self.type_hints
Example #55
0
 def _annotations(self):
     return get_type_hints(self)
def generate(t: Any) -> None:
    print("")
    class_name = short_name(t)
    base_class = t.__bases__[0].__name__
    base_sync_class = ("AsyncBase" if base_class == "ChannelOwner"
                       or base_class == "object" else base_class)
    print(f"class {class_name}({base_sync_class}):")
    print("")
    print(f"    def __init__(self, obj: {class_name}Impl):")
    print("        super().__init__(obj)")
    for [name, type] in get_type_hints(t, api_globals).items():
        print("")
        print("    @property")
        print(f"    def {to_snake_case(name)}(self) -> {process_type(type)}:")
        documentation_provider.print_entry(class_name, to_snake_case(name),
                                           {"return": type})
        [prefix, suffix] = return_value(type)
        prefix = "        return " + prefix + f"self._impl_obj.{name}"
        print(f"{prefix}{suffix}")
    for [name, value] in t.__dict__.items():
        if name.startswith("_"):
            continue
        if not name.startswith("_") and str(value).startswith("<property"):
            value = value.fget
            print("")
            print("    @property")
            print(
                f"    def {to_snake_case(name)}({signature(value, len(name) + 9)}) -> {return_type(value)}:"
            )
            documentation_provider.print_entry(
                class_name, to_snake_case(name),
                get_type_hints(value, api_globals))
            [prefix, suffix
             ] = return_value(get_type_hints(value, api_globals)["return"])
            prefix = "        return " + prefix + f"self._impl_obj.{name}"
            print(f"{prefix}{arguments(value, len(prefix))}{suffix}")
    for [name, value] in t.__dict__.items():
        if (not name.startswith("_") and isinstance(value, FunctionType)
                and "expect_" not in name and "remove_listener" != name):
            is_async = inspect.iscoroutinefunction(value)
            print("")
            async_prefix = "async " if is_async else ""
            await_prefix = "await " if is_async else ""
            print(
                f"    {async_prefix}def {to_snake_case(name)}({signature(value, len(name) + 9)}) -> {return_type(value)}:"
            )
            documentation_provider.print_entry(
                class_name, to_snake_case(name),
                get_type_hints(value, api_globals))
            [prefix, suffix
             ] = return_value(get_type_hints(value, api_globals)["return"])
            prefix = prefix + f"{await_prefix}self._impl_obj.{name}("
            suffix = ")" + suffix
            print(f"""
        try:
            log_api("=> {to_snake_case(class_name)}.{to_snake_case(name)} started")
            result = {prefix}{arguments(value, len(prefix))}{suffix}
            log_api("<= {to_snake_case(class_name)}.{to_snake_case(name)} succeded")
            return result
        except Exception as e:
            log_api("<= {to_snake_case(class_name)}.{to_snake_case(name)} failed")
            raise e""")
        if "expect_" in name:
            print("")
            return_type_value = return_type(value)
            return_type_value = re.sub(r"\"([^\"]+)Impl\"", r"\1",
                                       return_type_value)
            event_name = re.sub(r"expect_(.*)", r"\1", name)
            event_name = re.sub(r"_", "", event_name)
            event_name = re.sub(r"consolemessage", "console", event_name)

            print(
                f"""    def {to_snake_case(name)}({signature(value, len(name) + 9)}) -> Async{return_type_value}:
        \"\"\"{class_name}.{name}

        Returns context manager that waits for ``event`` to fire upon exit. It passes event's value
        into the ``predicate`` function and waits for the predicate to return a truthy value. Will throw
        an error if the page is closed before the ``event`` is fired.

        async with page.expect_{event_name}() as event_info:
            await page.click("button")
        value = event_info.value

        Parameters
        ----------
        predicate : Optional[typing.Callable[[Any], bool]]
            Predicate receiving event data.
        timeout : Optional[int]
            Maximum wait time in milliseconds, defaults to 30 seconds, pass `0` to disable the timeout.
            The default value can be changed by using the browserContext.setDefaultTimeout(timeout) or
            page.setDefaultTimeout(timeout) methods.
        \"\"\"""")

            wait_for_method = "waitForEvent(event, predicate, timeout)"
            if event_name == "request":
                wait_for_method = "waitForRequest(url_or_predicate, timeout)"
            elif event_name == "response":
                wait_for_method = "waitForResponse(url_or_predicate, timeout)"
            elif event_name == "loadstate":
                wait_for_method = "waitForLoadState(state, timeout)"
            elif event_name == "navigation":
                wait_for_method = "waitForNavigation(url, wait_until, timeout)"
            elif event_name != "event":
                print(f'        event = "{event_name}"')

            print(
                f"        return AsyncEventContextManager(self._impl_obj.{wait_for_method})"
            )

    print("")
    print(f"mapping.register({class_name}Impl, {class_name})")
Example #57
0
    def register_handler(
            self, call: Callable[[Any, Message], Optional[Response]]) -> None:
        """Register a handler call.

        The message type handled by the call is determined by its
        type annotation.
        """
        # TODO: can use types.GenericAlias in 3.9.
        from typing import _GenericAlias  # type: ignore
        from typing import Union, get_type_hints, get_args

        sig = inspect.getfullargspec(call)

        # The provided callable should be a method taking one 'msg' arg.
        expectedsig = ['self', 'msg']
        if sig.args != expectedsig:
            raise ValueError(f'Expected callable signature of {expectedsig};'
                             f' got {sig.args}')

        # Check annotation types to determine what message types we handle.
        # Return-type annotation can be a Union, but we probably don't
        # have it available at runtime. Explicitly pull it in.
        anns = get_type_hints(call, localns={'Union': Union})
        msgtype = anns.get('msg')
        if not isinstance(msgtype, type):
            raise TypeError(
                f'expected a type for "msg" annotation; got {type(msgtype)}.')
        assert issubclass(msgtype, Message)

        ret = anns.get('return')
        responsetypes: Tuple[Union[Type[Any], Type[None]], ...]

        # Return types can be a single type or a union of types.
        if isinstance(ret, _GenericAlias):
            targs = get_args(ret)
            if not all(isinstance(a, type) for a in targs):
                raise TypeError(f'expected only types for "return" annotation;'
                                f' got {targs}.')
            responsetypes = targs
        else:
            if not isinstance(ret, type):
                raise TypeError(f'expected one or more types for'
                                f' "return" annotation; got a {type(ret)}.')
            responsetypes = (ret, )

        # Return type of None translates to EmptyResponse.
        responsetypes = tuple(EmptyResponse if r is type(None) else r
                              for r in responsetypes)

        # Make sure our protocol has this message type registered and our
        # return types exactly match. (Technically we could return a subset
        # of the supported types; can allow this in the future if it makes
        # sense).
        registered_types = self._protocol.message_ids_by_type.keys()

        if msgtype not in registered_types:
            raise TypeError(f'Message type {msgtype} is not registered'
                            f' in this Protocol.')

        if msgtype in self._handlers:
            raise TypeError(f'Message type {msgtype} already has a registered'
                            f' handler.')

        # Make sure the responses exactly matches what the message expects.
        if set(responsetypes) != set(msgtype.get_response_types()):
            raise TypeError(
                f'Provided response types {responsetypes} do not'
                f' match the set expected by message type {msgtype}: '
                f'({msgtype.get_response_types()})')

        # Ok; we're good!
        self._handlers[msgtype] = call
Example #58
0
 def test_typing_present(self):
     assert is_palindromic.__hints__ == typing.get_type_hints(self.is_palindromic_oracle)
Example #59
0
 def test_typing_present(self):
     assert leap.__hints__ == typing.get_type_hints(self.leap_oracle)
Example #60
0
    def __validate_types__(  # pylint: disable=too-many-branches; # noqa: C901
        cls: Type["BasePropTypes"], ) -> None:
        """Validate the types of the props defined in the current PropTypes class.

        Raises
        ------
        PropTypeChoicesError

            - If a prop is a ``Choices`` with no value or empty list.
            - If a prop is a ``Choices`` with something else than a list.

        PropTypeRequiredError

            - If a prop is a ``DefaultChoices`` and is marked as ``Required``.
            - For all other props marked as ``Required`` if there is a value.

        InvalidPropValueError

            - If the default value is not valid for the prop type.

        """
        cls.__types__ = {
            name: prop_type
            for name, prop_type in get_type_hints(cls).items()
            if not hasattr(BasePropTypes, name)
            and name not in cls.__excluded_props__
        }

        for name, prop_type in cls.__types__.items():

            is_required = False

            try:
                if issubclass(prop_type, Required):
                    is_required = True
            except TypeError:
                try:
                    if prop_type.__origin__ is Required:
                        is_required = True
                except AttributeError:
                    pass

            if is_required:
                prop_type = prop_type.__args__[0]
                cls.__types__[name] = prop_type
                cls.__required_props__.add(name)

            if cls.__is_choice__(name):

                if not getattr(cls, name, []):
                    raise PropTypeChoicesError(
                        cls.__owner_name__,
                        name,
                        "a 'choices' prop must have a list of values",
                    )

                choices = getattr(cls, name)

                if not isinstance(choices, Sequence) or isinstance(
                        choices, str):
                    raise PropTypeChoicesError(
                        cls.__owner_name__,
                        name,
                        "the value for a 'choices' prop must be a list",
                    )

                if issubclass(cls.__type__(name), DefaultChoices):
                    if choices[0] is not NotProvided:
                        if is_required:
                            raise PropTypeRequiredError(
                                cls.__owner_name__,
                                name,
                                "a 'choices' prop with a default value cannot be required",
                            )
                        cls.__default_props__[name] = choices[0]

                continue

            default = getattr(cls, name, NotProvided)
            if default is NotProvided:
                continue

            if is_required:
                raise PropTypeRequiredError(
                    cls.__owner_name__,
                    name,
                    "a prop with a default value cannot be required",
                )

            cls.__default_props__[name] = cls.__validate__(name, default)