Esempio n. 1
0
    def lookup_concrete(self, tvar):
        """Find a set representative, which is either a concrete type, or the first element."""
        if not isinstance(tvar, TypeVar):
            return tvar

        i = self._find(tvar)
        the_set = self._sets[i]

        rep = None
        for t in the_set:
            if rep is None:
                rep = t
            elif not _type_vars([t]):
                rep = t
            elif (isinstance(t, CallableMeta) or isinstance(t, TuplePlus)
                  or isinstance(t, GenericMeta)) and isinstance(rep, TypeVar):
                rep = t

        if isinstance(rep, CallableMeta):
            return _gorg(
                rep)[[self.lookup_concrete(t1) for t1 in rep.__args__[:-1]],
                     self.lookup_concrete(rep.__args__[-1])]
        elif isinstance(rep, GenericMeta):
            return _gorg(rep)[tuple(
                self.lookup_concrete(t1) for t1 in rep.__args__)]
        return rep or tvar
Esempio n. 2
0
    def __new__(cls, name, bases, namespace,
                tvars=None, args=None, origin=None, extra=None, orig_bases=None):
        # This is just a version copied from GenericMeta.__new__ that
        # includes "Protocol" special treatment. (Comments removed for brevity.)
        assert extra is None  # Protocols should not have extra
        if tvars is not None:
            assert origin is not None
            assert all(isinstance(t, TypeVar) for t in tvars), tvars
        else:
            tvars = _type_vars(bases)
            gvars = None
            for base in bases:
                if base is Generic:
                    raise TypeError("Cannot inherit from plain Generic")
                if (isinstance(base, GenericMeta) and
                        base.__origin__ in (Generic, Protocol)):
                    if gvars is not None:
                        raise TypeError(
                            "Cannot inherit from Generic[...] or"
                            " Protocol[...] multiple times.")
                    gvars = base.__parameters__
            if gvars is None:
                gvars = tvars
            else:
                tvarset = set(tvars)
                gvarset = set(gvars)
                if not tvarset <= gvarset:
                    raise TypeError(
                        "Some type variables (%s) "
                        "are not listed in %s[%s]" %
                        (", ".join(str(t) for t in tvars if t not in gvarset),
                         "Generic" if any(b.__origin__ is Generic
                                          for b in bases) else "Protocol",
                         ", ".join(str(g) for g in gvars)))
                tvars = gvars

        initial_bases = bases
        if extra is None:
            extra = namespace.get('__extra__')
        if extra is not None and type(extra) is abc.ABCMeta and extra not in bases:
            bases = (extra,) + bases
        bases = tuple(_gorg(b) if isinstance(b, GenericMeta) else b for b in bases)

        if any(isinstance(b, GenericMeta) and b is not Generic for b in bases):
            bases = tuple(b for b in bases if b is not Generic)
        namespace.update({'__origin__': origin, '__extra__': extra})
        self = abc.ABCMeta.__new__(cls, name, bases, namespace)
        abc.ABCMeta.__setattr__(self, '_gorg', self if not origin else _gorg(origin))

        self.__parameters__ = tvars
        self.__args__ = tuple(Ellipsis if a is _TypingEllipsis else
                              () if a is _TypingEmpty else
                              a for a in args) if args else None
        self.__next_in_mro__ = _next_in_mro(self)
        if orig_bases is None:
            self.__orig_bases__ = initial_bases
        self.__tree_hash__ = (hash(self._subs_tree()) if origin else
                              abc.ABCMeta.__hash__(self))
        return self
Esempio n. 3
0
    def __new__(cls, name, bases, namespace,
                tvars=None, args=None, origin=None, extra=None, orig_bases=None):
        # This is just a version copied from GenericMeta.__new__ that
        # includes "Protocol" special treatment. (Comments removed for brevity.)
        assert extra is None  # Protocols should not have extra
        if tvars is not None:
            assert origin is not None
            assert all(isinstance(t, TypeVar) for t in tvars), tvars
        else:
            tvars = _type_vars(bases)
            gvars = None
            for base in bases:
                if base is Generic:
                    raise TypeError("Cannot inherit from plain Generic")
                if (isinstance(base, GenericMeta) and
                        base.__origin__ in (Generic, Protocol)):
                    if gvars is not None:
                        raise TypeError(
                            "Cannot inherit from Generic[...] or"
                            " Protocol[...] multiple times.")
                    gvars = base.__parameters__
            if gvars is None:
                gvars = tvars
            else:
                tvarset = set(tvars)
                gvarset = set(gvars)
                if not tvarset <= gvarset:
                    raise TypeError(
                        "Some type variables (%s) "
                        "are not listed in %s[%s]" %
                        (", ".join(str(t) for t in tvars if t not in gvarset),
                         "Generic" if any(b.__origin__ is Generic
                                          for b in bases) else "Protocol",
                         ", ".join(str(g) for g in gvars)))
                tvars = gvars

        initial_bases = bases
        if extra is None:
            extra = namespace.get('__extra__')
        if extra is not None and type(extra) is abc.ABCMeta and extra not in bases:
            bases = (extra,) + bases
        bases = tuple(_gorg(b) if isinstance(b, GenericMeta) else b for b in bases)

        if any(isinstance(b, GenericMeta) and b is not Generic for b in bases):
            bases = tuple(b for b in bases if b is not Generic)
        namespace.update({'__origin__': origin, '__extra__': extra})
        self = abc.ABCMeta.__new__(cls, name, bases, namespace)
        abc.ABCMeta.__setattr__(self, '_gorg', self if not origin else _gorg(origin))

        self.__parameters__ = tvars
        self.__args__ = tuple(Ellipsis if a is _TypingEllipsis else
                              () if a is _TypingEmpty else
                              a for a in args) if args else None
        self.__next_in_mro__ = _next_in_mro(self)
        if orig_bases is None:
            self.__orig_bases__ = initial_bases
        self.__tree_hash__ = (hash(self._subs_tree()) if origin else
                              abc.ABCMeta.__hash__(self))
        return self
Esempio n. 4
0
            def __getitem__(self, params):
                # We also need to copy this from GenericMeta.__getitem__ to get
                # special treatment of "Protocol". (Comments removed for brevity.)
                if not isinstance(params, tuple):
                    params = (params, )
                if not params and _gorg(self) is not Tuple:
                    raise TypeError(
                        "Parameter list to %s[...] cannot be empty" %
                        self.__qualname__)
                msg = "Parameters to generic types must be types."
                params = tuple(_type_check(p, msg) for p in params)
                if self in (Generic, Protocol):
                    if not all(isinstance(p, TypeVar) for p in params):
                        raise TypeError(
                            "Parameters to %r[...] must all be type variables"
                            % self)
                    if len(set(params)) != len(params):
                        raise TypeError(
                            "Parameters to %r[...] must all be unique" % self)
                    tvars = params
                    args = params
                elif self in (Tuple, Callable):
                    tvars = _type_vars(params)
                    args = params
                elif self.__origin__ in (Generic, Protocol):
                    raise TypeError("Cannot subscript already-subscripted %s" %
                                    repr(self))
                else:
                    _check_generic(self, params)
                    tvars = _type_vars(params)
                    args = params

                prepend = (self, ) if self.__origin__ is None else ()
                return self.__class__(self.__name__,
                                      prepend + self.__bases__,
                                      _no_slots_copy(self.__dict__),
                                      tvars=tvars,
                                      args=args,
                                      origin=self,
                                      extra=self.__extra__,
                                      orig_bases=self.__orig_bases__)
Esempio n. 5
0
    def __getitem__(self, params):
        # We also need to copy this from GenericMeta.__getitem__ to get
        # special treatment of "Protocol". (Comments removed for brevity.)
        if not isinstance(params, tuple):
            params = (params,)
        if not params and _gorg(self) is not Tuple:
            raise TypeError(
                "Parameter list to %s[...] cannot be empty" % self.__qualname__)
        msg = "Parameters to generic types must be types."
        params = tuple(_type_check(p, msg) for p in params)
        if self in (Generic, Protocol):
            if not all(isinstance(p, TypeVar) for p in params):
                raise TypeError(
                    "Parameters to %r[...] must all be type variables", self)
            if len(set(params)) != len(params):
                raise TypeError(
                    "Parameters to %r[...] must all be unique", self)
            tvars = params
            args = params
        elif self in (Tuple, Callable):
            tvars = _type_vars(params)
            args = params
        elif self.__origin__ in (Generic, Protocol):
            raise TypeError("Cannot subscript already-subscripted %s" %
                            repr(self))
        else:
            _check_generic(self, params)
            tvars = _type_vars(params)
            args = params

        prepend = (self,) if self.__origin__ is None else ()
        return self.__class__(self.__name__,
                              prepend + self.__bases__,
                              dict(self.__dict__),
                              tvars=tvars,
                              args=args,
                              origin=self,
                              extra=self.__extra__,
                              orig_bases=self.__orig_bases__)
Esempio n. 6
0
 def __getitem__(self, params):
     if not isinstance(params, tuple):
         params = (params, )
     if self.__origin__ is not None:  # specializing an instantiated type
         return super(AnnotatedMeta, self).__getitem__(params)
     elif not isinstance(params, tuple) or len(params) < 2:
         raise TypeError("Annotated[...] should be instantiated with at "
                         "least two arguments (a type and an annotation).")
     else:
         msg = "Annotated[t, ...]: t must be a type."
         tp = typing._type_check(params[0], msg)
         metadata = tuple(params[1:])
     return self.__class__(
         self.__name__,
         self.__bases__,
         dict(self.__dict__),
         tvars=_type_vars((tp, )),
         # Metadata is a tuple so it won't be touched by _replace_args et al.
         args=(tp, metadata),
         origin=self,
     )