Kaydet (Commit) 6a2dc1bd authored tarafından Guido van Rossum's avatar Guido van Rossum

Merge upstream typing.py changes from 3.5 branch.

import asyncio
import pickle
import re
import sys
from unittest import TestCase, main
from unittest import TestCase, main, skipUnless
from typing import Any
from typing import TypeVar, AnyStr
......@@ -133,6 +132,7 @@ class TypeVarTests(TestCase):
def test_constrained_error(self):
with self.assertRaises(TypeError):
X = TypeVar('X', int)
X
def test_union_unique(self):
X = TypeVar('X')
......@@ -317,6 +317,7 @@ class UnionTests(TestCase):
def test_union_str_pattern(self):
# Shouldn't crash; see http://bugs.python.org/issue25390
A = Union[str, Pattern]
A
class TypeVarUnionTests(TestCase):
......@@ -487,7 +488,7 @@ class SimpleMapping(Generic[XK, XV]):
...
class MySimpleMapping(SimpleMapping):
class MySimpleMapping(SimpleMapping[XK, XV]):
def __init__(self):
self.store = {}
......@@ -541,6 +542,7 @@ class ProtocolTests(TestCase):
assert not issubclass(str, typing.SupportsAbs)
def test_supports_round(self):
issubclass(float, typing.SupportsRound)
assert issubclass(float, typing.SupportsRound)
assert issubclass(int, typing.SupportsRound)
assert not issubclass(str, typing.SupportsRound)
......@@ -551,20 +553,23 @@ class ProtocolTests(TestCase):
def test_protocol_instance_type_error(self):
with self.assertRaises(TypeError):
isinstance([], typing.Reversible)
isinstance(0, typing.SupportsAbs)
class GenericTests(TestCase):
def test_basics(self):
X = SimpleMapping[str, Any]
Y = SimpleMapping[XK, str]
X[str, str]
Y[str, str]
assert X.__parameters__ == ()
with self.assertRaises(TypeError):
X[int, str]
X[str]
with self.assertRaises(TypeError):
X[str, str]
Y = SimpleMapping[XK, str]
assert Y.__parameters__ == (XK,)
Y[str]
with self.assertRaises(TypeError):
Y[str, bytes]
Y[str, str]
def test_init(self):
T = TypeVar('T')
......@@ -576,30 +581,61 @@ class GenericTests(TestCase):
def test_repr(self):
self.assertEqual(repr(SimpleMapping),
__name__ + '.' + 'SimpleMapping[~XK, ~XV]')
__name__ + '.' + 'SimpleMapping<~XK, ~XV>')
self.assertEqual(repr(MySimpleMapping),
__name__ + '.' + 'MySimpleMapping[~XK, ~XV]')
__name__ + '.' + 'MySimpleMapping<~XK, ~XV>')
def test_chain_repr(self):
T = TypeVar('T')
S = TypeVar('S')
class C(Generic[T]):
pass
X = C[Tuple[S, T]]
assert X == C[Tuple[S, T]]
assert X != C[Tuple[T, S]]
Y = X[T, int]
assert Y == X[T, int]
assert Y != X[S, int]
assert Y != X[T, str]
Z = Y[str]
assert Z == Y[str]
assert Z != Y[int]
assert Z != Y[T]
assert str(Z).endswith(
'.C<~T>[typing.Tuple[~S, ~T]]<~S, ~T>[~T, int]<~T>[str]')
def test_dict(self):
T = TypeVar('T')
class B(Generic[T]):
pass
b = B()
b.foo = 42
self.assertEqual(b.__dict__, {'foo': 42})
class C(B[int]):
pass
c = C()
c.bar = 'abc'
self.assertEqual(c.__dict__, {'bar': 'abc'})
def test_pickle(self):
global C # pickle wants to reference the class by name
T = TypeVar('T')
class B(Generic[T]):
pass
global C # pickle wants to reference the class by name
class C(B[int]):
pass
c = C()
c.foo = 42
c.bar = 'abc'
......@@ -626,12 +662,12 @@ class GenericTests(TestCase):
assert C.__module__ == __name__
if not PY32:
assert C.__qualname__ == 'GenericTests.test_repr_2.<locals>.C'
assert repr(C).split('.')[-1] == 'C[~T]'
assert repr(C).split('.')[-1] == 'C<~T>'
X = C[int]
assert X.__module__ == __name__
if not PY32:
assert X.__qualname__ == 'C'
assert repr(X).split('.')[-1] == 'C[int]'
assert repr(X).split('.')[-1] == 'C<~T>[int]'
class Y(C[int]):
pass
......@@ -639,7 +675,7 @@ class GenericTests(TestCase):
assert Y.__module__ == __name__
if not PY32:
assert Y.__qualname__ == 'GenericTests.test_repr_2.<locals>.Y'
assert repr(Y).split('.')[-1] == 'Y[int]'
assert repr(Y).split('.')[-1] == 'Y'
def test_eq_1(self):
assert Generic == Generic
......@@ -667,15 +703,14 @@ class GenericTests(TestCase):
class B(Generic[KT, T]):
pass
class C(A, Generic[KT, VT], B):
class C(A[T, VT], Generic[VT, T, KT], B[KT, T]):
pass
assert C.__parameters__ == (T, VT, KT)
assert C.__parameters__ == (VT, T, KT)
def test_nested(self):
class G(Generic):
pass
G = Generic
class Visitor(G[T]):
......@@ -721,9 +756,30 @@ class GenericTests(TestCase):
assert type(a) is Node
assert type(b) is Node
assert type(c) is Node
assert a.label == x
assert b.label == x
assert c.label == x
foo(42)
def test_implicit_any(self):
T = TypeVar('T')
class C(Generic[T]):
pass
class D(C):
pass
assert D.__parameters__ == ()
with self.assertRaises(Exception):
D[int]
with self.assertRaises(Exception):
D[Any]
with self.assertRaises(Exception):
D[T]
class VarianceTests(TestCase):
......@@ -956,13 +1012,32 @@ class OverloadTests(TestCase):
from typing import overload
with self.assertRaises(RuntimeError):
@overload
def blah():
pass
blah()
T_a = TypeVar('T')
def test_overload_succeeds(self):
from typing import overload
@overload
def blah():
pass
def blah():
pass
blah()
PY35 = sys.version_info[:2] >= (3, 5)
PY35_TESTS = """
import asyncio
T_a = TypeVar('T')
class AwaitableWrapper(typing.Awaitable[T_a]):
......@@ -973,7 +1048,6 @@ class AwaitableWrapper(typing.Awaitable[T_a]):
yield
return self.value
class AsyncIteratorWrapper(typing.AsyncIterator[T_a]):
def __init__(self, value: typing.Iterable[T_a]):
......@@ -989,6 +1063,10 @@ class AsyncIteratorWrapper(typing.AsyncIterator[T_a]):
return data
else:
raise StopAsyncIteration
"""
if PY35:
exec(PY35_TESTS)
class CollectionsAbcTests(TestCase):
......@@ -1015,9 +1093,14 @@ class CollectionsAbcTests(TestCase):
assert isinstance(it, typing.Iterator[int])
assert not isinstance(42, typing.Iterator)
@skipUnless(PY35, 'Python 3.5 required')
def test_awaitable(self):
async def foo() -> typing.Awaitable[int]:
return await AwaitableWrapper(42)
ns = {}
exec(
"async def foo() -> typing.Awaitable[int]:\n"
" return await AwaitableWrapper(42)\n",
globals(), ns)
foo = ns['foo']
g = foo()
assert issubclass(type(g), typing.Awaitable[int])
assert isinstance(g, typing.Awaitable)
......@@ -1028,6 +1111,7 @@ class CollectionsAbcTests(TestCase):
typing.Awaitable[Manager])
g.send(None) # Run foo() till completion, to avoid warning.
@skipUnless(PY35, 'Python 3.5 required')
def test_async_iterable(self):
base_it = range(10) # type: Iterator[int]
it = AsyncIteratorWrapper(base_it)
......@@ -1037,6 +1121,7 @@ class CollectionsAbcTests(TestCase):
typing.AsyncIterable[Employee])
assert not isinstance(42, typing.AsyncIterable)
@skipUnless(PY35, 'Python 3.5 required')
def test_async_iterator(self):
base_it = range(10) # type: Iterator[int]
it = AsyncIteratorWrapper(base_it)
......@@ -1127,6 +1212,22 @@ class CollectionsAbcTests(TestCase):
d = MyDict()
assert isinstance(d, MyDict)
def test_no_defaultdict_instantiation(self):
with self.assertRaises(TypeError):
typing.DefaultDict()
with self.assertRaises(TypeError):
typing.DefaultDict[KT, VT]()
with self.assertRaises(TypeError):
typing.DefaultDict[str, int]()
def test_defaultdict_subclass_instantiation(self):
class MyDefDict(typing.DefaultDict[str, int]):
pass
dd = MyDefDict()
assert isinstance(dd, MyDefDict)
def test_no_set_instantiation(self):
with self.assertRaises(TypeError):
typing.Set()
......@@ -1251,7 +1352,7 @@ class IOTests(TestCase):
return a.readline()
a = stuff.__annotations__['a']
assert a.__parameters__ == (str,)
assert a.__parameters__ == ()
def test_binaryio(self):
......@@ -1259,7 +1360,7 @@ class IOTests(TestCase):
return a.readline()
a = stuff.__annotations__['a']
assert a.__parameters__ == (bytes,)
assert a.__parameters__ == ()
def test_io_submodule(self):
from typing.io import IO, TextIO, BinaryIO, __all__, __name__
......@@ -1346,8 +1447,9 @@ class AllTests(TestCase):
assert 'ValuesView' in a
assert 'cast' in a
assert 'overload' in a
assert 'io' in a
assert 're' in a
# Check that io and re are not exported.
assert 'io' not in a
assert 're' not in a
# Spot-check that stdlib modules aren't exported.
assert 'os' not in a
assert 'sys' not in a
......
# TODO nits:
# Get rid of asserts that are the caller's fault.
# Docstrings (e.g. ABCs).
import abc
from abc import abstractmethod, abstractproperty
import collections
......@@ -56,6 +52,7 @@ __all__ = [
# Concrete collection types.
'Dict',
'DefaultDict',
'List',
'Set',
'NamedTuple', # Not really a type.
......@@ -68,12 +65,12 @@ __all__ = [
'no_type_check',
'no_type_check_decorator',
'overload',
# Submodules.
'io',
're',
]
# The pseudo-submodules 're' and 'io' are part of the public
# namespace, but excluded from __all__ because they might stomp on
# legitimate imports of those modules.
def _qualname(x):
if sys.version_info[:2] >= (3, 3):
......@@ -117,8 +114,8 @@ class TypingMeta(type):
"""
return self
def _has_type_var(self):
return False
def _get_type_vars(self, tvars):
pass
def __repr__(self):
return '%s.%s' % (self.__module__, _qualname(self))
......@@ -214,8 +211,8 @@ class _TypeAlias:
someone tries to subclass a type alias (not a good idea).
"""
if (len(args) == 3 and
isinstance(args[0], str) and
isinstance(args[1], tuple)):
isinstance(args[0], str) and
isinstance(args[1], tuple)):
# Close enough.
raise TypeError("A type alias cannot be subclassed")
return object.__new__(cls)
......@@ -271,8 +268,16 @@ class _TypeAlias:
return issubclass(cls, self.impl_type)
def _has_type_var(t):
return t is not None and isinstance(t, TypingMeta) and t._has_type_var()
def _get_type_vars(types, tvars):
for t in types:
if isinstance(t, TypingMeta):
t._get_type_vars(tvars)
def _type_vars(types):
tvars = []
_get_type_vars(types, tvars)
return tuple(tvars)
def _eval_type(t, globalns, localns):
......@@ -376,7 +381,7 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
At runtime, isinstance(x, T) will raise TypeError. However,
issubclass(C, T) is true for any class C, and issubclass(str, A)
and issubclass(bytes, A) are true, and issubclass(int, A) is
false.
false. (TODO: Why is this needed? This may change. See #136.)
Type variables may be marked covariant or contravariant by passing
covariant=True or contravariant=True. See PEP 484 for more
......@@ -410,8 +415,9 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
self.__bound__ = None
return self
def _has_type_var(self):
return True
def _get_type_vars(self, tvars):
if self not in tvars:
tvars.append(self)
def __repr__(self):
if self.__covariant__:
......@@ -448,7 +454,6 @@ VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers.
T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant.
# A useful type variable with constraints. This represents string types.
# TODO: What about bytearray, memoryview?
AnyStr = TypeVar('AnyStr', bytes, str)
......@@ -514,12 +519,9 @@ class UnionMeta(TypingMeta):
return self.__class__(self.__name__, self.__bases__, {},
p, _root=True)
def _has_type_var(self):
def _get_type_vars(self, tvars):
if self.__union_params__:
for t in self.__union_params__:
if _has_type_var(t):
return True
return False
_get_type_vars(self.__union_params__, tvars)
def __repr__(self):
r = super().__repr__()
......@@ -656,12 +658,9 @@ class TupleMeta(TypingMeta):
self.__tuple_use_ellipsis__ = use_ellipsis
return self
def _has_type_var(self):
def _get_type_vars(self, tvars):
if self.__tuple_params__:
for t in self.__tuple_params__:
if _has_type_var(t):
return True
return False
_get_type_vars(self.__tuple_params__, tvars)
def _eval_type(self, globalns, localns):
tp = self.__tuple_params__
......@@ -769,12 +768,9 @@ class CallableMeta(TypingMeta):
self.__result__ = result
return self
def _has_type_var(self):
def _get_type_vars(self, tvars):
if self.__args__:
for t in self.__args__:
if _has_type_var(t):
return True
return _has_type_var(self.__result__)
_get_type_vars(self.__args__, tvars)
def _eval_type(self, globalns, localns):
if self.__args__ is None and self.__result__ is None:
......@@ -878,76 +874,106 @@ def _geqv(a, b):
return _gorg(a) is _gorg(b)
class GenericMeta(TypingMeta, abc.ABCMeta):
"""Metaclass for generic types."""
def _next_in_mro(cls):
"""Helper for Generic.__new__.
Returns the class after the last occurrence of Generic or
Generic[...] in cls.__mro__.
"""
next_in_mro = object
# Look for the last occurrence of Generic or Generic[...].
for i, c in enumerate(cls.__mro__[:-1]):
if isinstance(c, GenericMeta) and _gorg(c) is Generic:
next_in_mro = cls.__mro__[i+1]
return next_in_mro
# TODO: Constrain more how Generic is used; only a few
# standard patterns should be allowed.
# TODO: Use a more precise rule than matching __name__ to decide
# whether two classes are the same. Also, save the formal
# parameters. (These things are related! A solution lies in
# using origin.)
class GenericMeta(TypingMeta, abc.ABCMeta):
"""Metaclass for generic types."""
__extra__ = None
def __new__(cls, name, bases, namespace,
parameters=None, origin=None, extra=None):
if parameters is None:
# Extract parameters from direct base classes. Only
# direct bases are considered and only those that are
# themselves generic, and parameterized with type
# variables. Don't use bases like Any, Union, Tuple,
# Callable or type variables.
params = None
tvars=None, args=None, origin=None, extra=None):
self = super().__new__(cls, name, bases, namespace, _root=True)
if tvars is not None:
# Called from __getitem__() below.
assert origin is not None
assert all(isinstance(t, TypeVar) for t in tvars), tvars
else:
# Called from class statement.
assert tvars is None, tvars
assert args is None, args
assert origin is None, origin
# Get the full set of tvars from the bases.
tvars = _type_vars(bases)
# Look for Generic[T1, ..., Tn].
# If found, tvars must be a subset of it.
# If not found, tvars is it.
# Also check for and reject plain Generic,
# and reject multiple Generic[...].
gvars = None
for base in bases:
if isinstance(base, TypingMeta):
if not isinstance(base, GenericMeta):
if base is Generic:
raise TypeError("Cannot inherit from plain Generic")
if (isinstance(base, GenericMeta) and
base.__origin__ is Generic):
if gvars is not None:
raise TypeError(
"You cannot inherit from magic class %s" %
repr(base))
if base.__parameters__ is None:
continue # The base is unparameterized.
for bp in base.__parameters__:
if _has_type_var(bp) and not isinstance(bp, TypeVar):
raise TypeError(
"Cannot inherit from a generic class "
"parameterized with "
"non-type-variable %s" % bp)
if params is None:
params = []
if bp not in params:
params.append(bp)
if params is not None:
parameters = tuple(params)
self = super().__new__(cls, name, bases, namespace, _root=True)
self.__parameters__ = parameters
"Cannot inherit from Generic[...] multiple types.")
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 Generic[%s]" %
(", ".join(str(t) for t in tvars if t not in gvarset),
", ".join(str(g) for g in gvars)))
tvars = gvars
self.__parameters__ = tvars
self.__args__ = args
self.__origin__ = origin
if extra is not None:
self.__extra__ = extra
# Else __extra__ is inherited, eventually from the
# (meta-)class default above.
self.__origin__ = origin
# Speed hack (https://github.com/python/typing/issues/196).
self.__next_in_mro__ = _next_in_mro(self)
return self
def _has_type_var(self):
if self.__parameters__:
for t in self.__parameters__:
if _has_type_var(t):
return True
return False
def _get_type_vars(self, tvars):
if self.__origin__ and self.__parameters__:
_get_type_vars(self.__parameters__, tvars)
def __repr__(self):
r = super().__repr__()
if self.__parameters__ is not None:
if self.__origin__ is not None:
r = repr(self.__origin__)
else:
r = super().__repr__()
if self.__args__:
r += '[%s]' % (
', '.join(_type_repr(p) for p in self.__args__))
if self.__parameters__:
r += '<%s>' % (
', '.join(_type_repr(p) for p in self.__parameters__))
return r
def __eq__(self, other):
if not isinstance(other, GenericMeta):
return NotImplemented
return (_geqv(self, other) and
self.__parameters__ == other.__parameters__)
if self.__origin__ is not None:
return (self.__origin__ is other.__origin__ and
self.__args__ == other.__args__ and
self.__parameters__ == other.__parameters__)
else:
return self is other
def __hash__(self):
return hash((self.__name__, self.__parameters__))
......@@ -956,37 +982,45 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
if not isinstance(params, tuple):
params = (params,)
if not params:
raise TypeError("Cannot have empty parameter list")
raise TypeError(
"Parameter list to %s[...] cannot be empty" % _qualname(self))
msg = "Parameters to generic types must be types."
params = tuple(_type_check(p, msg) for p in params)
if self.__parameters__ is None:
for p in params:
if not isinstance(p, TypeVar):
raise TypeError("Initial parameters must be "
"type variables; got %s" % p)
if self is Generic:
# Generic can only be subscripted with unique type variables.
if not all(isinstance(p, TypeVar) for p in params):
raise TypeError(
"Parameters to Generic[...] must all be type variables")
if len(set(params)) != len(params):
raise TypeError(
"All type variables in Generic[...] must be distinct.")
"Parameters to Generic[...] must all be unique")
tvars = params
args = None
elif self is _Protocol:
# _Protocol is internal, don't check anything.
tvars = params
args = None
elif self.__origin__ in (Generic, _Protocol):
# Can't subscript Generic[...] or _Protocol[...].
raise TypeError("Cannot subscript already-subscripted %s" %
repr(self))
else:
if len(params) != len(self.__parameters__):
raise TypeError("Cannot change parameter count from %d to %d" %
(len(self.__parameters__), len(params)))
for new, old in zip(params, self.__parameters__):
if isinstance(old, TypeVar):
if not old.__constraints__:
# Substituting for an unconstrained TypeVar is OK.
continue
if issubclass(new, Union[old.__constraints__]):
# Specializing a constrained type variable is OK.
continue
if not issubclass(new, old):
raise TypeError(
"Cannot substitute %s for %s in %s" %
(_type_repr(new), _type_repr(old), self))
return self.__class__(self.__name__, (self,) + self.__bases__,
# Subscripting a regular Generic subclass.
if not self.__parameters__:
raise TypeError("%s is not a generic class" % repr(self))
alen = len(params)
elen = len(self.__parameters__)
if alen != elen:
raise TypeError(
"Too %s parameters for %s; actual %s, expected %s" %
("many" if alen > elen else "few", repr(self), alen, elen))
tvars = _type_vars(params)
args = params
return self.__class__(self.__name__,
(self,) + self.__bases__,
dict(self.__dict__),
parameters=params,
tvars=tvars,
args=args,
origin=self,
extra=self.__extra__)
......@@ -1006,10 +1040,10 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
# C[X] is a subclass of C[Y] iff X is a subclass of Y.
origin = self.__origin__
if origin is not None and origin is cls.__origin__:
assert len(self.__parameters__) == len(origin.__parameters__)
assert len(cls.__parameters__) == len(origin.__parameters__)
for p_self, p_cls, p_origin in zip(self.__parameters__,
cls.__parameters__,
assert len(self.__args__) == len(origin.__parameters__)
assert len(cls.__args__) == len(origin.__parameters__)
for p_self, p_cls, p_origin in zip(self.__args__,
cls.__args__,
origin.__parameters__):
if isinstance(p_origin, TypeVar):
if p_origin.__covariant__:
......@@ -1039,6 +1073,10 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
return issubclass(cls, self.__extra__)
# Prevent checks for Generic to crash when defining Generic.
Generic = None
class Generic(metaclass=GenericMeta):
"""Abstract base class for generic types.
......@@ -1053,29 +1091,23 @@ class Generic(metaclass=GenericMeta):
This class can then be used as follows::
def lookup_name(mapping: Mapping, key: KT, default: VT) -> VT:
def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
try:
return mapping[key]
except KeyError:
return default
For clarity the type variables may be redefined, e.g.::
X = TypeVar('X')
Y = TypeVar('Y')
def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y:
# Same body as above.
"""
__slots__ = ()
def __new__(cls, *args, **kwds):
next_in_mro = object
# Look for the last occurrence of Generic or Generic[...].
for i, c in enumerate(cls.__mro__[:-1]):
if isinstance(c, GenericMeta) and _gorg(c) is Generic:
next_in_mro = cls.__mro__[i+1]
return next_in_mro.__new__(_gorg(cls))
if cls.__origin__ is None:
return cls.__next_in_mro__.__new__(cls)
else:
origin = _gorg(cls)
obj = cls.__next_in_mro__.__new__(origin)
obj.__init__(*args, **kwds)
return obj
def cast(typ, val):
......@@ -1093,9 +1125,7 @@ def _get_defaults(func):
"""Internal helper to extract the default arguments, by name."""
code = func.__code__
pos_count = code.co_argcount
kw_count = code.co_kwonlyargcount
arg_names = code.co_varnames
kwarg_names = arg_names[pos_count:pos_count + kw_count]
arg_names = arg_names[:pos_count]
defaults = func.__defaults__ or ()
kwdefaults = func.__kwdefaults__
......@@ -1148,7 +1178,6 @@ def get_type_hints(obj, globalns=None, localns=None):
return hints
# TODO: Also support this as a class decorator.
def no_type_check(arg):
"""Decorator to indicate that annotations are not type hints.
......@@ -1183,8 +1212,42 @@ def no_type_check_decorator(decorator):
return wrapped_decorator
def _overload_dummy(*args, **kwds):
"""Helper for @overload to raise when called."""
raise NotImplementedError(
"You should not call an overloaded function. "
"A series of @overload-decorated functions "
"outside a stub module should always be followed "
"by an implementation that is not @overload-ed.")
def overload(func):
raise RuntimeError("Overloading is only supported in library stubs")
"""Decorator for overloaded functions/methods.
In a stub file, place two or more stub definitions for the same
function in a row, each decorated with @overload. For example:
@overload
def utf8(value: None) -> None: ...
@overload
def utf8(value: bytes) -> bytes: ...
@overload
def utf8(value: str) -> bytes: ...
In a non-stub file (i.e. a regular .py file), do the same but
follow it with an implementation. The implementation should *not*
be decorated with @overload. For example:
@overload
def utf8(value: None) -> None: ...
@overload
def utf8(value: bytes) -> bytes: ...
@overload
def utf8(value: str) -> bytes: ...
def utf8(value):
# implementation goes here
"""
return _overload_dummy
class _ProtocolMeta(GenericMeta):
......@@ -1232,14 +1295,16 @@ class _ProtocolMeta(GenericMeta):
break
else:
if (not attr.startswith('_abc_') and
attr != '__abstractmethods__' and
attr != '_is_protocol' and
attr != '__dict__' and
attr != '__slots__' and
attr != '_get_protocol_attrs' and
attr != '__parameters__' and
attr != '__origin__' and
attr != '__module__'):
attr != '__abstractmethods__' and
attr != '_is_protocol' and
attr != '__dict__' and
attr != '__args__' and
attr != '__slots__' and
attr != '_get_protocol_attrs' and
attr != '__next_in_mro__' and
attr != '__parameters__' and
attr != '__origin__' and
attr != '__module__'):
attrs.add(attr)
return attrs
......@@ -1264,16 +1329,25 @@ class _Protocol(metaclass=_ProtocolMeta):
Hashable = collections_abc.Hashable # Not generic.
class Awaitable(Generic[T_co], extra=collections_abc.Awaitable):
__slots__ = ()
if hasattr(collections_abc, 'Awaitable'):
class Awaitable(Generic[T_co], extra=collections_abc.Awaitable):
__slots__ = ()
else:
Awaitable = None
class AsyncIterable(Generic[T_co], extra=collections_abc.AsyncIterable):
__slots__ = ()
if hasattr(collections_abc, 'AsyncIterable'):
class AsyncIterable(Generic[T_co], extra=collections_abc.AsyncIterable):
__slots__ = ()
class AsyncIterator(AsyncIterable[T_co], extra=collections_abc.AsyncIterator):
__slots__ = ()
class AsyncIterator(AsyncIterable[T_co],
extra=collections_abc.AsyncIterator):
__slots__ = ()
else:
AsyncIterable = None
AsyncIterator = None
class Iterable(Generic[T_co], extra=collections_abc.Iterable):
......@@ -1332,12 +1406,16 @@ class SupportsRound(_Protocol[T_co]):
pass
class Reversible(_Protocol[T_co]):
__slots__ = ()
if hasattr(collections_abc, 'Reversible'):
class Reversible(Iterable[T_co], extra=collections_abc.Reversible):
__slots__ = ()
else:
class Reversible(_Protocol[T_co]):
__slots__ = ()
@abstractmethod
def __reversed__(self) -> 'Iterator[T_co]':
pass
@abstractmethod
def __reversed__(self) -> 'Iterator[T_co]':
pass
Sized = collections_abc.Sized # Not generic.
......@@ -1360,7 +1438,7 @@ class MutableSet(AbstractSet[T], extra=collections_abc.MutableSet):
# NOTE: Only the value type is covariant.
class Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co],
class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co],
extra=collections_abc.Mapping):
pass
......@@ -1368,10 +1446,14 @@ class Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co],
class MutableMapping(Mapping[KT, VT], extra=collections_abc.MutableMapping):
pass
class Sequence(Sized, Iterable[T_co], Container[T_co],
if hasattr(collections_abc, 'Reversible'):
class Sequence(Sized, Reversible[T_co], Container[T_co],
extra=collections_abc.Sequence):
pass
pass
else:
class Sequence(Sized, Iterable[T_co], Container[T_co],
extra=collections_abc.Sequence):
pass
class MutableSequence(Sequence[T], extra=collections_abc.MutableSequence):
......@@ -1436,8 +1518,9 @@ class KeysView(MappingView[KT], AbstractSet[KT],
pass
# TODO: Enable Set[Tuple[KT, VT_co]] instead of Generic[KT, VT_co].
class ItemsView(MappingView, Generic[KT, VT_co],
class ItemsView(MappingView[Tuple[KT, VT_co]],
Set[Tuple[KT, VT_co]],
Generic[KT, VT_co],
extra=collections_abc.ItemsView):
pass
......@@ -1454,6 +1537,13 @@ class Dict(dict, MutableMapping[KT, VT]):
"use dict() instead")
return dict.__new__(cls, *args, **kwds)
class DefaultDict(collections.defaultdict, MutableMapping[KT, VT]):
def __new__(cls, *args, **kwds):
if _geqv(cls, DefaultDict):
raise TypeError("Type DefaultDict cannot be instantiated; "
"use collections.defaultdict() instead")
return collections.defaultdict.__new__(cls, *args, **kwds)
# Determine what base class to use for Generator.
if hasattr(collections_abc, 'Generator'):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment