Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
6a2dc1bd
Kaydet (Commit)
6a2dc1bd
authored
Nis 05, 2016
tarafından
Guido van Rossum
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Sade Fark
Merge upstream typing.py changes from 3.5 branch.
üst
b15c3049
bd5b9a07
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
371 additions
and
179 deletions
+371
-179
test_typing.py
Lib/test/test_typing.py
+129
-27
typing.py
Lib/typing.py
+242
-152
No files found.
Lib/test/test_typing.py
Dosyayı görüntüle @
6a2dc1bd
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
,
V
T
,
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
...
...
Lib/typing.py
Dosyayı görüntüle @
6a2dc1bd
# 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
.
__
parameter
s__
)
==
len
(
origin
.
__parameters__
)
assert
len
(
cls
.
__
parameter
s__
)
==
len
(
origin
.
__parameters__
)
for
p_self
,
p_cls
,
p_origin
in
zip
(
self
.
__
parameter
s__
,
cls
.
__
parameter
s__
,
assert
len
(
self
.
__
arg
s__
)
==
len
(
origin
.
__parameters__
)
assert
len
(
cls
.
__
arg
s__
)
==
len
(
origin
.
__parameters__
)
for
p_self
,
p_cls
,
p_origin
in
zip
(
self
.
__
arg
s__
,
cls
.
__
arg
s__
,
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
,
Itera
ble
[
T_co
],
Container
[
T_co
],
if
hasattr
(
collections_abc
,
'Reversible'
):
class
Sequence
(
Sized
,
Reversi
ble
[
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'
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment