Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
4cefe74a
Commit
4cefe74a
authored
Sep 27, 2016
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update typing.py and test_typing.py from upstream (
https://github.com/python/typing
)
parent
63461bc3
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
416 additions
and
562 deletions
+416
-562
Lib/test/test_typing.py
Lib/test/test_typing.py
+114
-223
Lib/typing.py
Lib/typing.py
+302
-339
No files found.
Lib/test/test_typing.py
View file @
4cefe74a
...
...
@@ -9,7 +9,7 @@ from typing import Any
from
typing
import
TypeVar
,
AnyStr
from
typing
import
T
,
KT
,
VT
# Not in __all__.
from
typing
import
Union
,
Optional
from
typing
import
Tuple
,
List
from
typing
import
Tuple
,
List
,
MutableMapping
from
typing
import
Callable
from
typing
import
Generic
,
ClassVar
from
typing
import
cast
...
...
@@ -21,6 +21,10 @@ from typing import NamedTuple
from
typing
import
IO
,
TextIO
,
BinaryIO
from
typing
import
Pattern
,
Match
import
typing
try
:
import
collections.abc
as
collections_abc
except
ImportError
:
import
collections
as
collections_abc
# Fallback for PY3.2.
class
BaseTestCase
(
TestCase
):
...
...
@@ -62,18 +66,11 @@ class AnyTests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
isinstance
(
42
,
Any
)
def
test_any_subclass
(
self
):
self
.
assertTrue
(
issubclass
(
Employee
,
Any
))
self
.
assertTrue
(
issubclass
(
int
,
Any
))
self
.
assertTrue
(
issubclass
(
type
(
None
),
Any
))
self
.
assertTrue
(
issubclass
(
object
,
Any
))
def
test_others_any
(
self
):
self
.
assertFalse
(
issubclass
(
Any
,
Employee
))
self
.
assertFalse
(
issubclass
(
Any
,
int
))
self
.
assertFalse
(
issubclass
(
Any
,
type
(
None
)))
# However, Any is a subclass of object (this can't be helped).
self
.
assertTrue
(
issubclass
(
Any
,
object
))
def
test_any_subclass_type_error
(
self
):
with
self
.
assertRaises
(
TypeError
):
issubclass
(
Employee
,
Any
)
with
self
.
assertRaises
(
TypeError
):
issubclass
(
Any
,
Employee
)
def
test_repr
(
self
):
self
.
assertEqual
(
repr
(
Any
),
'typing.Any'
)
...
...
@@ -88,32 +85,21 @@ class AnyTests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
class
A
(
Any
):
pass
with
self
.
assertRaises
(
TypeError
):
class
A
(
type
(
Any
)):
pass
def
test_cannot_instantiate
(
self
):
with
self
.
assertRaises
(
TypeError
):
Any
()
with
self
.
assertRaises
(
TypeError
):
type
(
Any
)()
def
test_cannot_subscript
(
self
):
with
self
.
assertRaises
(
TypeError
):
Any
[
int
]
def
test_any_is_subclass
(
self
):
# Any should be considered a subclass of everything.
self
.
assertIsSubclass
(
Any
,
Any
)
self
.
assertIsSubclass
(
Any
,
typing
.
List
)
self
.
assertIsSubclass
(
Any
,
typing
.
List
[
int
])
self
.
assertIsSubclass
(
Any
,
typing
.
List
[
T
])
self
.
assertIsSubclass
(
Any
,
typing
.
Mapping
)
self
.
assertIsSubclass
(
Any
,
typing
.
Mapping
[
str
,
int
])
self
.
assertIsSubclass
(
Any
,
typing
.
Mapping
[
KT
,
VT
])
self
.
assertIsSubclass
(
Any
,
Generic
)
self
.
assertIsSubclass
(
Any
,
Generic
[
T
])
self
.
assertIsSubclass
(
Any
,
Generic
[
KT
,
VT
])
self
.
assertIsSubclass
(
Any
,
AnyStr
)
self
.
assertIsSubclass
(
Any
,
Union
)
self
.
assertIsSubclass
(
Any
,
Union
[
int
,
str
])
self
.
assertIsSubclass
(
Any
,
typing
.
Match
)
self
.
assertIsSubclass
(
Any
,
typing
.
Match
[
str
])
def
test_any_works_with_alias
(
self
):
# These expressions must simply not fail.
typing
.
Match
[
Any
]
typing
.
Pattern
[
Any
]
...
...
@@ -124,13 +110,8 @@ class TypeVarTests(BaseTestCase):
def
test_basic_plain
(
self
):
T
=
TypeVar
(
'T'
)
# Every class is a subclass of T.
self
.
assertIsSubclass
(
int
,
T
)
self
.
assertIsSubclass
(
str
,
T
)
# T equals itself.
self
.
assertEqual
(
T
,
T
)
# T is a subclass of itself.
self
.
assertIsSubclass
(
T
,
T
)
# T is an instance of TypeVar
self
.
assertIsInstance
(
T
,
TypeVar
)
...
...
@@ -139,16 +120,12 @@ class TypeVarTests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
isinstance
(
42
,
T
)
def
test_basic_constrained
(
self
):
A
=
TypeVar
(
'A'
,
str
,
bytes
)
# Only str and bytes are subclasses of A.
self
.
assertIsSubclass
(
str
,
A
)
self
.
assertIsSubclass
(
bytes
,
A
)
self
.
assertNotIsSubclass
(
int
,
A
)
# A equals itself.
self
.
assertEqual
(
A
,
A
)
# A is a subclass of itself.
self
.
assertIsSubclass
(
A
,
A
)
def
test_typevar_subclass_type_error
(
self
):
T
=
TypeVar
(
'T'
)
with
self
.
assertRaises
(
TypeError
):
issubclass
(
int
,
T
)
with
self
.
assertRaises
(
TypeError
):
issubclass
(
T
,
int
)
def
test_constrained_error
(
self
):
with
self
.
assertRaises
(
TypeError
):
...
...
@@ -185,19 +162,6 @@ class TypeVarTests(BaseTestCase):
self
.
assertNotEqual
(
TypeVar
(
'T'
),
TypeVar
(
'T'
))
self
.
assertNotEqual
(
TypeVar
(
'T'
,
int
,
str
),
TypeVar
(
'T'
,
int
,
str
))
def
test_subclass_as_unions
(
self
):
# None of these are true -- each type var is its own world.
self
.
assertFalse
(
issubclass
(
TypeVar
(
'T'
,
int
,
str
),
TypeVar
(
'T'
,
int
,
str
)))
self
.
assertFalse
(
issubclass
(
TypeVar
(
'T'
,
int
,
float
),
TypeVar
(
'T'
,
int
,
float
,
str
)))
self
.
assertFalse
(
issubclass
(
TypeVar
(
'T'
,
int
,
str
),
TypeVar
(
'T'
,
str
,
int
)))
A
=
TypeVar
(
'A'
,
int
,
str
)
B
=
TypeVar
(
'B'
,
int
,
str
,
float
)
self
.
assertFalse
(
issubclass
(
A
,
B
))
self
.
assertFalse
(
issubclass
(
B
,
A
))
def
test_cannot_subclass_vars
(
self
):
with
self
.
assertRaises
(
TypeError
):
class
V
(
TypeVar
(
'T'
)):
...
...
@@ -212,12 +176,6 @@ class TypeVarTests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
TypeVar
(
'A'
)()
def
test_bound
(
self
):
X
=
TypeVar
(
'X'
,
bound
=
Employee
)
self
.
assertIsSubclass
(
Employee
,
X
)
self
.
assertIsSubclass
(
Manager
,
X
)
self
.
assertNotIsSubclass
(
int
,
X
)
def
test_bound_errors
(
self
):
with
self
.
assertRaises
(
TypeError
):
TypeVar
(
'X'
,
bound
=
42
)
...
...
@@ -230,8 +188,16 @@ class UnionTests(BaseTestCase):
def
test_basics
(
self
):
u
=
Union
[
int
,
float
]
self
.
assertNotEqual
(
u
,
Union
)
self
.
assertTrue
(
issubclass
(
int
,
u
))
self
.
assertTrue
(
issubclass
(
float
,
u
))
def
test_subclass_error
(
self
):
with
self
.
assertRaises
(
TypeError
):
issubclass
(
int
,
Union
)
with
self
.
assertRaises
(
TypeError
):
issubclass
(
Union
,
int
)
with
self
.
assertRaises
(
TypeError
):
issubclass
(
int
,
Union
[
int
,
str
])
with
self
.
assertRaises
(
TypeError
):
issubclass
(
Union
[
int
,
str
],
int
)
def
test_union_any
(
self
):
u
=
Union
[
Any
]
...
...
@@ -260,18 +226,6 @@ class UnionTests(BaseTestCase):
u2
=
Union
[
float
,
int
]
self
.
assertEqual
(
u1
,
u2
)
def
test_subclass
(
self
):
u
=
Union
[
int
,
Employee
]
self
.
assertTrue
(
issubclass
(
Manager
,
u
))
def
test_self_subclass
(
self
):
self
.
assertTrue
(
issubclass
(
Union
[
KT
,
VT
],
Union
))
self
.
assertFalse
(
issubclass
(
Union
,
Union
[
KT
,
VT
]))
def
test_multiple_inheritance
(
self
):
u
=
Union
[
int
,
Employee
]
self
.
assertTrue
(
issubclass
(
ManagingFounder
,
u
))
def
test_single_class_disappears
(
self
):
t
=
Union
[
Employee
]
self
.
assertIs
(
t
,
Employee
)
...
...
@@ -284,13 +238,6 @@ class UnionTests(BaseTestCase):
u
=
Union
[
Employee
,
Manager
]
self
.
assertIs
(
u
,
Employee
)
def
test_weird_subclasses
(
self
):
u
=
Union
[
Employee
,
int
,
float
]
v
=
Union
[
int
,
float
]
self
.
assertTrue
(
issubclass
(
v
,
u
))
w
=
Union
[
int
,
Manager
]
self
.
assertTrue
(
issubclass
(
w
,
u
))
def
test_union_union
(
self
):
u
=
Union
[
int
,
float
]
v
=
Union
[
u
,
Employee
]
...
...
@@ -307,6 +254,9 @@ class UnionTests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
class
C
(
Union
):
pass
with
self
.
assertRaises
(
TypeError
):
class
C
(
type
(
Union
)):
pass
with
self
.
assertRaises
(
TypeError
):
class
C
(
Union
[
int
,
str
]):
pass
...
...
@@ -314,9 +264,18 @@ class UnionTests(BaseTestCase):
def
test_cannot_instantiate
(
self
):
with
self
.
assertRaises
(
TypeError
):
Union
()
with
self
.
assertRaises
(
TypeError
):
type
(
Union
)()
u
=
Union
[
int
,
float
]
with
self
.
assertRaises
(
TypeError
):
u
()
with
self
.
assertRaises
(
TypeError
):
type
(
u
)()
def
test_union_generalization
(
self
):
self
.
assertFalse
(
Union
[
str
,
typing
.
Iterable
[
int
]]
==
str
)
self
.
assertFalse
(
Union
[
str
,
typing
.
Iterable
[
int
]]
==
typing
.
Iterable
[
int
])
self
.
assertTrue
(
Union
[
str
,
typing
.
Iterable
]
==
typing
.
Iterable
)
def
test_optional
(
self
):
o
=
Optional
[
int
]
...
...
@@ -327,10 +286,6 @@ class UnionTests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
Union
[()]
def
test_issubclass_union
(
self
):
self
.
assertIsSubclass
(
Union
[
int
,
str
],
Union
)
self
.
assertNotIsSubclass
(
int
,
Union
)
def
test_union_instance_type_error
(
self
):
with
self
.
assertRaises
(
TypeError
):
isinstance
(
42
,
Union
[
int
,
str
])
...
...
@@ -355,43 +310,19 @@ class UnionTests(BaseTestCase):
Union
[
Elem
,
str
]
# Nor should this
class
TypeVarUnionTests
(
BaseTestCase
):
def
test_simpler
(
self
):
A
=
TypeVar
(
'A'
,
int
,
str
,
float
)
B
=
TypeVar
(
'B'
,
int
,
str
)
self
.
assertIsSubclass
(
A
,
A
)
self
.
assertIsSubclass
(
B
,
B
)
self
.
assertNotIsSubclass
(
B
,
A
)
self
.
assertIsSubclass
(
A
,
Union
[
int
,
str
,
float
])
self
.
assertNotIsSubclass
(
Union
[
int
,
str
,
float
],
A
)
self
.
assertNotIsSubclass
(
Union
[
int
,
str
],
B
)
self
.
assertIsSubclass
(
B
,
Union
[
int
,
str
])
self
.
assertNotIsSubclass
(
A
,
B
)
self
.
assertNotIsSubclass
(
Union
[
int
,
str
,
float
],
B
)
self
.
assertNotIsSubclass
(
A
,
Union
[
int
,
str
])
def
test_var_union_subclass
(
self
):
self
.
assertTrue
(
issubclass
(
T
,
Union
[
int
,
T
]))
self
.
assertTrue
(
issubclass
(
KT
,
Union
[
KT
,
VT
]))
def
test_var_union
(
self
):
TU
=
TypeVar
(
'TU'
,
Union
[
int
,
float
],
None
)
self
.
assertIsSubclass
(
int
,
TU
)
self
.
assertIsSubclass
(
float
,
TU
)
class
TupleTests
(
BaseTestCase
):
def
test_basics
(
self
):
self
.
assertTrue
(
issubclass
(
Tuple
[
int
,
str
],
Tuple
))
self
.
assertTrue
(
issubclass
(
Tuple
[
int
,
str
],
Tuple
[
int
,
str
]))
self
.
assertFalse
(
issubclass
(
int
,
Tuple
))
self
.
assertFalse
(
issubclass
(
Tuple
[
float
,
str
],
Tuple
[
int
,
str
]))
self
.
assertFalse
(
issubclass
(
Tuple
[
int
,
str
,
int
],
Tuple
[
int
,
str
]))
self
.
assertFalse
(
issubclass
(
Tuple
[
int
,
str
],
Tuple
[
int
,
str
,
int
]))
with
self
.
assertRaises
(
TypeError
):
issubclass
(
Tuple
[
int
,
str
],
Tuple
)
with
self
.
assertRaises
(
TypeError
):
issubclass
(
Tuple
,
Tuple
[
int
,
str
])
with
self
.
assertRaises
(
TypeError
):
issubclass
(
tuple
,
Tuple
[
int
,
str
])
class
TP
(
tuple
):
...
self
.
assertTrue
(
issubclass
(
tuple
,
Tuple
))
self
.
assert
False
(
issubclass
(
Tuple
,
tuple
))
# Can't have it both ways.
self
.
assert
True
(
issubclass
(
TP
,
Tuple
))
def
test_equality
(
self
):
self
.
assertEqual
(
Tuple
[
int
],
Tuple
[
int
])
...
...
@@ -407,21 +338,7 @@ class TupleTests(BaseTestCase):
def
test_tuple_instance_type_error
(
self
):
with
self
.
assertRaises
(
TypeError
):
isinstance
((
0
,
0
),
Tuple
[
int
,
int
])
with
self
.
assertRaises
(
TypeError
):
isinstance
((
0
,
0
),
Tuple
)
def
test_tuple_ellipsis_subclass
(
self
):
class
B
:
pass
class
C
(
B
):
pass
self
.
assertNotIsSubclass
(
Tuple
[
B
],
Tuple
[
B
,
...])
self
.
assertIsSubclass
(
Tuple
[
C
,
...],
Tuple
[
B
,
...])
self
.
assertNotIsSubclass
(
Tuple
[
C
,
...],
Tuple
[
B
])
self
.
assertNotIsSubclass
(
Tuple
[
C
],
Tuple
[
B
,
...])
self
.
assertIsInstance
((
0
,
0
),
Tuple
)
def
test_repr
(
self
):
self
.
assertEqual
(
repr
(
Tuple
),
'typing.Tuple'
)
...
...
@@ -439,17 +356,9 @@ class TupleTests(BaseTestCase):
class
CallableTests
(
BaseTestCase
):
def
test_self_subclass
(
self
):
self
.
assertTrue
(
issubclass
(
Callable
[[
int
],
int
],
Callable
))
self
.
assertFalse
(
issubclass
(
Callable
,
Callable
[[
int
],
int
]))
self
.
assertTrue
(
issubclass
(
Callable
[[
int
],
int
],
Callable
[[
int
],
int
]))
self
.
assertFalse
(
issubclass
(
Callable
[[
Employee
],
int
],
Callable
[[
Manager
],
int
]))
self
.
assertFalse
(
issubclass
(
Callable
[[
Manager
],
int
],
Callable
[[
Employee
],
int
]))
self
.
assertFalse
(
issubclass
(
Callable
[[
int
],
Employee
],
Callable
[[
int
],
Manager
]))
self
.
assertFalse
(
issubclass
(
Callable
[[
int
],
Manager
],
Callable
[[
int
],
Employee
]))
with
self
.
assertRaises
(
TypeError
):
self
.
assertTrue
(
issubclass
(
type
(
lambda
x
:
x
),
Callable
[[
int
],
int
]))
self
.
assertTrue
(
issubclass
(
type
(
lambda
x
:
x
),
Callable
))
def
test_eq_hash
(
self
):
self
.
assertEqual
(
Callable
[[
int
],
int
],
Callable
[[
int
],
int
])
...
...
@@ -466,6 +375,11 @@ class CallableTests(BaseTestCase):
class
C
(
Callable
):
pass
with
self
.
assertRaises
(
TypeError
):
class
C
(
type
(
Callable
)):
pass
with
self
.
assertRaises
(
TypeError
):
class
C
(
Callable
[[
int
],
int
]):
...
...
@@ -474,9 +388,13 @@ class CallableTests(BaseTestCase):
def
test_cannot_instantiate
(
self
):
with
self
.
assertRaises
(
TypeError
):
Callable
()
with
self
.
assertRaises
(
TypeError
):
type
(
Callable
)()
c
=
Callable
[[
int
],
str
]
with
self
.
assertRaises
(
TypeError
):
c
()
with
self
.
assertRaises
(
TypeError
):
type
(
c
)()
def
test_callable_instance_works
(
self
):
def
f
():
...
...
@@ -616,6 +534,12 @@ class GenericTests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
Y
[
str
,
str
]
def
test_generic_errors
(
self
):
with
self
.
assertRaises
(
TypeError
):
isinstance
([],
List
[
int
])
with
self
.
assertRaises
(
TypeError
):
issubclass
(
list
,
List
[
int
])
def
test_init
(
self
):
T
=
TypeVar
(
'T'
)
S
=
TypeVar
(
'S'
)
...
...
@@ -671,6 +595,42 @@ class GenericTests(BaseTestCase):
c
.
bar
=
'abc'
self
.
assertEqual
(
c
.
__dict__
,
{
'bar'
:
'abc'
})
def
test_false_subclasses
(
self
):
class
MyMapping
(
MutableMapping
[
str
,
str
]):
pass
self
.
assertNotIsInstance
({},
MyMapping
)
self
.
assertNotIsSubclass
(
dict
,
MyMapping
)
def
test_multiple_abc_bases
(
self
):
class
MM1
(
MutableMapping
[
str
,
str
],
collections_abc
.
MutableMapping
):
def
__getitem__
(
self
,
k
):
return
None
def
__setitem__
(
self
,
k
,
v
):
pass
def
__delitem__
(
self
,
k
):
pass
def
__iter__
(
self
):
return
iter
(())
def
__len__
(
self
):
return
0
class
MM2
(
collections_abc
.
MutableMapping
,
MutableMapping
[
str
,
str
]):
def
__getitem__
(
self
,
k
):
return
None
def
__setitem__
(
self
,
k
,
v
):
pass
def
__delitem__
(
self
,
k
):
pass
def
__iter__
(
self
):
return
iter
(())
def
__len__
(
self
):
return
0
# these two should just work
MM1
().
update
()
MM2
().
update
()
self
.
assertIsInstance
(
MM1
(),
collections_abc
.
MutableMapping
)
self
.
assertIsInstance
(
MM1
(),
MutableMapping
)
self
.
assertIsInstance
(
MM2
(),
collections_abc
.
MutableMapping
)
self
.
assertIsInstance
(
MM2
(),
MutableMapping
)
def
test_pickle
(
self
):
global
C
# pickle wants to reference the class by name
T
=
TypeVar
(
'T'
)
...
...
@@ -853,6 +813,8 @@ class ClassVarTests(BaseTestCase):
pass
def
test_cannot_init
(
self
):
with
self
.
assertRaises
(
TypeError
):
ClassVar
()
with
self
.
assertRaises
(
TypeError
):
type
(
ClassVar
)()
with
self
.
assertRaises
(
TypeError
):
...
...
@@ -865,52 +827,6 @@ class ClassVarTests(BaseTestCase):
issubclass
(
int
,
ClassVar
)
class
VarianceTests
(
BaseTestCase
):
def
test_invariance
(
self
):
# Because of invariance, List[subclass of X] is not a subclass
# of List[X], and ditto for MutableSequence.
self
.
assertNotIsSubclass
(
typing
.
List
[
Manager
],
typing
.
List
[
Employee
])
self
.
assertNotIsSubclass
(
typing
.
MutableSequence
[
Manager
],
typing
.
MutableSequence
[
Employee
])
# It's still reflexive.
self
.
assertIsSubclass
(
typing
.
List
[
Employee
],
typing
.
List
[
Employee
])
self
.
assertIsSubclass
(
typing
.
MutableSequence
[
Employee
],
typing
.
MutableSequence
[
Employee
])
def
test_covariance_tuple
(
self
):
# Check covariace for Tuple (which are really special cases).
self
.
assertIsSubclass
(
Tuple
[
Manager
],
Tuple
[
Employee
])
self
.
assertNotIsSubclass
(
Tuple
[
Employee
],
Tuple
[
Manager
])
# And pairwise.
self
.
assertIsSubclass
(
Tuple
[
Manager
,
Manager
],
Tuple
[
Employee
,
Employee
])
self
.
assertNotIsSubclass
(
Tuple
[
Employee
,
Employee
],
Tuple
[
Manager
,
Employee
])
# And using ellipsis.
self
.
assertIsSubclass
(
Tuple
[
Manager
,
...],
Tuple
[
Employee
,
...])
self
.
assertNotIsSubclass
(
Tuple
[
Employee
,
...],
Tuple
[
Manager
,
...])
def
test_covariance_sequence
(
self
):
# Check covariance for Sequence (which is just a generic class
# for this purpose, but using a type variable with covariant=True).
self
.
assertIsSubclass
(
typing
.
Sequence
[
Manager
],
typing
.
Sequence
[
Employee
])
self
.
assertNotIsSubclass
(
typing
.
Sequence
[
Employee
],
typing
.
Sequence
[
Manager
])
def
test_covariance_mapping
(
self
):
# Ditto for Mapping (covariant in the value, invariant in the key).
self
.
assertIsSubclass
(
typing
.
Mapping
[
Employee
,
Manager
],
typing
.
Mapping
[
Employee
,
Employee
])
self
.
assertNotIsSubclass
(
typing
.
Mapping
[
Manager
,
Employee
],
typing
.
Mapping
[
Employee
,
Employee
])
self
.
assertNotIsSubclass
(
typing
.
Mapping
[
Employee
,
Manager
],
typing
.
Mapping
[
Manager
,
Manager
])
self
.
assertNotIsSubclass
(
typing
.
Mapping
[
Manager
,
Employee
],
typing
.
Mapping
[
Manager
,
Manager
])
class
CastTests
(
BaseTestCase
):
def
test_basics
(
self
):
...
...
@@ -1247,7 +1163,6 @@ class CollectionsAbcTests(BaseTestCase):
# path and could fail. So call this a few times.
self
.
assertIsInstance
([],
typing
.
Iterable
)
self
.
assertIsInstance
([],
typing
.
Iterable
)
self
.
assertIsInstance
([],
typing
.
Iterable
[
int
])
self
.
assertNotIsInstance
(
42
,
typing
.
Iterable
)
# Just in case, also test issubclass() a few times.
self
.
assertIsSubclass
(
list
,
typing
.
Iterable
)
...
...
@@ -1256,7 +1171,6 @@ class CollectionsAbcTests(BaseTestCase):
def
test_iterator
(
self
):
it
=
iter
([])
self
.
assertIsInstance
(
it
,
typing
.
Iterator
)
self
.
assertIsInstance
(
it
,
typing
.
Iterator
[
int
])
self
.
assertNotIsInstance
(
42
,
typing
.
Iterator
)
@
skipUnless
(
PY35
,
'Python 3.5 required'
)
...
...
@@ -1268,13 +1182,8 @@ class CollectionsAbcTests(BaseTestCase):
globals
(),
ns
)
foo
=
ns
[
'foo'
]
g
=
foo
()
self
.
assertIsSubclass
(
type
(
g
),
typing
.
Awaitable
[
int
])
self
.
assertIsInstance
(
g
,
typing
.
Awaitable
)
self
.
assertNotIsInstance
(
foo
,
typing
.
Awaitable
)
self
.
assertIsSubclass
(
typing
.
Awaitable
[
Manager
],
typing
.
Awaitable
[
Employee
])
self
.
assertNotIsSubclass
(
typing
.
Awaitable
[
Employee
],
typing
.
Awaitable
[
Manager
])
g
.
send
(
None
)
# Run foo() till completion, to avoid warning.
@
skipUnless
(
PY35
,
'Python 3.5 required'
)
...
...
@@ -1283,8 +1192,6 @@ class CollectionsAbcTests(BaseTestCase):
it
=
AsyncIteratorWrapper
(
base_it
)
self
.
assertIsInstance
(
it
,
typing
.
AsyncIterable
)
self
.
assertIsInstance
(
it
,
typing
.
AsyncIterable
)
self
.
assertIsSubclass
(
typing
.
AsyncIterable
[
Manager
],
typing
.
AsyncIterable
[
Employee
])
self
.
assertNotIsInstance
(
42
,
typing
.
AsyncIterable
)
@
skipUnless
(
PY35
,
'Python 3.5 required'
)
...
...
@@ -1292,8 +1199,6 @@ class CollectionsAbcTests(BaseTestCase):
base_it
=
range
(
10
)
# type: Iterator[int]
it
=
AsyncIteratorWrapper
(
base_it
)
self
.
assertIsInstance
(
it
,
typing
.
AsyncIterator
)
self
.
assertIsSubclass
(
typing
.
AsyncIterator
[
Manager
],
typing
.
AsyncIterator
[
Employee
])
self
.
assertNotIsInstance
(
42
,
typing
.
AsyncIterator
)
def
test_sized
(
self
):
...
...
@@ -1457,10 +1362,6 @@ class CollectionsAbcTests(BaseTestCase):
yield
42
g
=
foo
()
self
.
assertIsSubclass
(
type
(
g
),
typing
.
Generator
)
self
.
assertIsSubclass
(
typing
.
Generator
[
Manager
,
Employee
,
Manager
],
typing
.
Generator
[
Employee
,
Manager
,
Employee
])
self
.
assertNotIsSubclass
(
typing
.
Generator
[
Manager
,
Manager
,
Manager
],
typing
.
Generator
[
Employee
,
Employee
,
Employee
])
def
test_no_generator_instantiation
(
self
):
with
self
.
assertRaises
(
TypeError
):
...
...
@@ -1511,7 +1412,6 @@ class OtherABCTests(BaseTestCase):
cm
=
manager
()
self
.
assertIsInstance
(
cm
,
typing
.
ContextManager
)
self
.
assertIsInstance
(
cm
,
typing
.
ContextManager
[
int
])
self
.
assertNotIsInstance
(
42
,
typing
.
ContextManager
)
...
...
@@ -1653,22 +1553,16 @@ class RETests(BaseTestCase):
pat
=
re
.
compile
(
'[a-z]+'
,
re
.
I
)
self
.
assertIsSubclass
(
pat
.
__class__
,
Pattern
)
self
.
assertIsSubclass
(
type
(
pat
),
Pattern
)
self
.
assertIs
Subclass
(
type
(
pat
),
Pattern
[
str
]
)
self
.
assertIs
Instance
(
pat
,
Pattern
)
mat
=
pat
.
search
(
'12345abcde.....'
)
self
.
assertIsSubclass
(
mat
.
__class__
,
Match
)
self
.
assertIsSubclass
(
mat
.
__class__
,
Match
[
str
])
self
.
assertIsSubclass
(
mat
.
__class__
,
Match
[
bytes
])
# Sad but true.
self
.
assertIsSubclass
(
type
(
mat
),
Match
)
self
.
assertIs
Subclass
(
type
(
mat
),
Match
[
str
]
)
self
.
assertIs
Instance
(
mat
,
Match
)
# these should just work
p
=
Pattern
[
Union
[
str
,
bytes
]]
self
.
assertIsSubclass
(
Pattern
[
str
],
Pattern
)
self
.
assertIsSubclass
(
Pattern
[
str
],
p
)
m
=
Match
[
Union
[
bytes
,
str
]]
self
.
assertIsSubclass
(
Match
[
bytes
],
Match
)
self
.
assertIsSubclass
(
Match
[
bytes
],
m
)
def
test_errors
(
self
):
with
self
.
assertRaises
(
TypeError
):
...
...
@@ -1681,9 +1575,6 @@ class RETests(BaseTestCase):
with
self
.
assertRaises
(
TypeError
):
# Too complicated?
m
[
str
]
with
self
.
assertRaises
(
TypeError
):
# We don't support isinstance().
isinstance
(
42
,
Pattern
)
with
self
.
assertRaises
(
TypeError
):
# We don't support isinstance().
isinstance
(
42
,
Pattern
[
str
])
...
...
@@ -1710,7 +1601,7 @@ class RETests(BaseTestCase):
pass
self
.
assertEqual
(
str
(
ex
.
exception
),
"
A type alias cannot be subclassed
"
)
"
Cannot subclass typing._TypeAlias
"
)
class
AllTests
(
BaseTestCase
):
...
...
Lib/typing.py
View file @
4cefe74a
...
...
@@ -89,6 +89,13 @@ def _qualname(x):
return
x
.
__name__
def
_trim_name
(
nm
):
if
nm
.
startswith
(
'_'
)
and
nm
not
in
(
'_TypeAlias'
,
'_ForwardRef'
,
'_TypingBase'
,
'_FinalTypingBase'
):
nm
=
nm
[
1
:]
return
nm
class
TypingMeta
(
type
):
"""Metaclass for every type defined below.
...
...
@@ -127,22 +134,69 @@ class TypingMeta(type):
pass
def
__repr__
(
self
):
return
'%s.%s'
%
(
self
.
__module__
,
_qualname
(
self
))
qname
=
_trim_name
(
_qualname
(
self
))
return
'%s.%s'
%
(
self
.
__module__
,
qname
)
class
_TypingBase
(
metaclass
=
TypingMeta
,
_root
=
True
):
"""Indicator of special typing constructs."""
__slots__
=
()
def
__init__
(
self
,
*
args
,
**
kwds
):
pass
def
__new__
(
cls
,
*
args
,
**
kwds
):
"""Constructor.
This only exists to give a better error message in case
someone tries to subclass a special typing object (not a good idea).
"""
if
(
len
(
args
)
==
3
and
isinstance
(
args
[
0
],
str
)
and
isinstance
(
args
[
1
],
tuple
)):
# Close enough.
raise
TypeError
(
"Cannot subclass %r"
%
cls
)
return
object
.
__new__
(
cls
)
# Things that are not classes also need these.
def
_eval_type
(
self
,
globalns
,
localns
):
return
self
def
_get_type_vars
(
self
,
tvars
):
pass
def
__repr__
(
self
):
cls
=
type
(
self
)
qname
=
_trim_name
(
_qualname
(
cls
))
return
'%s.%s'
%
(
cls
.
__module__
,
qname
)
def
__call__
(
self
,
*
args
,
**
kwds
):
raise
TypeError
(
"Cannot instantiate %r"
%
type
(
self
))
class
Final
:
class
_FinalTypingBase
(
_TypingBase
,
_root
=
True
):
"""Mix-in class to prevent instantiation."""
__slots__
=
()
def
__new__
(
self
,
*
args
,
**
kwds
):
raise
TypeError
(
"Cannot instantiate %r"
%
self
.
__class__
)
def
__new__
(
cls
,
*
args
,
_root
=
False
,
**
kwds
):
self
=
super
().
__new__
(
cls
,
*
args
,
**
kwds
)
if
_root
is
True
:
return
self
raise
TypeError
(
"Cannot instantiate %r"
%
cls
)
class
_ForwardRef
(
TypingMeta
):
class
_ForwardRef
(
_TypingBase
,
_root
=
True
):
"""Wrapper to hold a forward reference."""
def
__new__
(
cls
,
arg
):
__slots__
=
(
'__forward_arg__'
,
'__forward_code__'
,
'__forward_evaluated__'
,
'__forward_value__'
,
'__forward_frame__'
)
def
__init__
(
self
,
arg
):
super
().
__init__
(
arg
)
if
not
isinstance
(
arg
,
str
):
raise
TypeError
(
'ForwardRef must be a string -- got %r'
%
(
arg
,))
try
:
...
...
@@ -150,7 +204,6 @@ class _ForwardRef(TypingMeta):
except
SyntaxError
:
raise
SyntaxError
(
'ForwardRef must be an expression -- got %r'
%
(
arg
,))
self
=
super
().
__new__
(
cls
,
arg
,
(),
{},
_root
=
True
)
self
.
__forward_arg__
=
arg
self
.
__forward_code__
=
code
self
.
__forward_evaluated__
=
False
...
...
@@ -161,7 +214,6 @@ class _ForwardRef(TypingMeta):
frame
=
frame
.
f_back
assert
frame
is
not
None
self
.
__forward_frame__
=
frame
return
self
def
_eval_type
(
self
,
globalns
,
localns
):
if
not
self
.
__forward_evaluated__
:
...
...
@@ -177,49 +229,36 @@ class _ForwardRef(TypingMeta):
self
.
__forward_evaluated__
=
True
return
self
.
__forward_value__
def
__eq__
(
self
,
other
):
if
not
isinstance
(
other
,
_ForwardRef
):
return
NotImplemented
return
(
self
.
__forward_arg__
==
other
.
__forward_arg__
and
self
.
__forward_frame__
==
other
.
__forward_frame__
)
def
__hash__
(
self
):
return
hash
((
self
.
__forward_arg__
,
self
.
__forward_frame__
))
def
__instancecheck__
(
self
,
obj
):
raise
TypeError
(
"Forward references cannot be used with isinstance()."
)
def
__subclasscheck__
(
self
,
cls
):
if
not
self
.
__forward_evaluated__
:
globalns
=
self
.
__forward_frame__
.
f_globals
localns
=
self
.
__forward_frame__
.
f_locals
try
:
self
.
_eval_type
(
globalns
,
localns
)
except
NameError
:
return
False
# Too early.
return
issubclass
(
cls
,
self
.
__forward_value__
)
raise
TypeError
(
"Forward references cannot be used with issubclass()."
)
def
__repr__
(
self
):
return
'_ForwardRef(%r)'
%
(
self
.
__forward_arg__
,)
class
_TypeAlias
:
class
_TypeAlias
(
_TypingBase
,
_root
=
True
)
:
"""Internal helper class for defining generic variants of concrete types.
Note that this is not a type; let's call it a pseudo-type. It can
be used in instance and subclass checks, e.g. isinstance(m, Match)
or issubclass(type(m), Match). However, it cannot be itself the
target of an issubclass() call; e.g. issubclass(Match, C) (for
some arbitrary class C) raises TypeError rather than returning
False.
Note that this is not a type; let's call it a pseudo-type. It cannot
be used in instance and subclass checks in parameterized form, i.e.
``isinstance(42, Match[str])`` raises ``TypeError`` instead of returning
``False``.
"""
__slots__
=
(
'name'
,
'type_var'
,
'impl_type'
,
'type_checker'
)
def
__new__
(
cls
,
*
args
,
**
kwds
):
"""Constructor.
This only exists to give a better error message in case
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
)):
# Close enough.
raise
TypeError
(
"A type alias cannot be subclassed"
)
return
object
.
__new__
(
cls
)
def
__init__
(
self
,
name
,
type_var
,
impl_type
,
type_checker
):
"""Initializer.
...
...
@@ -232,9 +271,9 @@ class _TypeAlias:
and returns a value that should be a type_var instance.
"""
assert
isinstance
(
name
,
str
),
repr
(
name
)
assert
isinstance
(
type_var
,
type
),
repr
(
type_var
)
assert
isinstance
(
impl_type
,
type
),
repr
(
impl_type
)
assert
not
isinstance
(
impl_type
,
TypingMeta
),
repr
(
impl_type
)
assert
isinstance
(
type_var
,
(
type
,
_TypingBase
))
self
.
name
=
name
self
.
type_var
=
type_var
self
.
impl_type
=
impl_type
...
...
@@ -244,36 +283,41 @@ class _TypeAlias:
return
"%s[%s]"
%
(
self
.
name
,
_type_repr
(
self
.
type_var
))
def
__getitem__
(
self
,
parameter
):
assert
isinstance
(
parameter
,
type
),
repr
(
parameter
)
if
not
isinstance
(
self
.
type_var
,
TypeVar
):
raise
TypeError
(
"%s cannot be further parameterized."
%
self
)
if
self
.
type_var
.
__constraints__
:
if
not
issubclass
(
parameter
,
Union
[
self
.
type_var
.
__constraints__
]
):
if
self
.
type_var
.
__constraints__
and
isinstance
(
parameter
,
type
)
:
if
not
issubclass
(
parameter
,
self
.
type_var
.
__constraints__
):
raise
TypeError
(
"%s is not a valid substitution for %s."
%
(
parameter
,
self
.
type_var
))
if
isinstance
(
parameter
,
TypeVar
):
raise
TypeError
(
"%s cannot be re-parameterized."
%
self
.
type_var
)
return
self
.
__class__
(
self
.
name
,
parameter
,
self
.
impl_type
,
self
.
type_checker
)
def
__eq__
(
self
,
other
):
if
not
isinstance
(
other
,
_TypeAlias
):
return
NotImplemented
return
self
.
name
==
other
.
name
and
self
.
type_var
==
other
.
type_var
def
__hash__
(
self
):
return
hash
((
self
.
name
,
self
.
type_var
))
def
__instancecheck__
(
self
,
obj
):
raise
TypeError
(
"Type aliases cannot be used with isinstance()."
)
if
not
isinstance
(
self
.
type_var
,
TypeVar
):
raise
TypeError
(
"Parameterized type aliases cannot be used "
"with isinstance()."
)
return
isinstance
(
obj
,
self
.
impl_type
)
def
__subclasscheck__
(
self
,
cls
):
if
cls
is
Any
:
return
True
if
isinstance
(
cls
,
_TypeAlias
):
# Covariance. For now, we compare by name.
return
(
cls
.
name
==
self
.
name
and
issubclass
(
cls
.
type_var
,
self
.
type_var
))
else
:
# Note that this is too lenient, because the
# implementation type doesn't carry information about
# whether it is about bytes or str (for example).
return
issubclass
(
cls
,
self
.
impl_type
)
if
not
isinstance
(
self
.
type_var
,
TypeVar
):
raise
TypeError
(
"Parameterized type aliases cannot be used "
"with issubclass()."
)
return
issubclass
(
cls
,
self
.
impl_type
)
def
_get_type_vars
(
types
,
tvars
):
for
t
in
types
:
if
isinstance
(
t
,
TypingMeta
)
or
isinstance
(
t
,
_
ClassVar
):
if
isinstance
(
t
,
TypingMeta
)
or
isinstance
(
t
,
_
TypingBase
):
t
.
_get_type_vars
(
tvars
)
...
...
@@ -284,7 +328,7 @@ def _type_vars(types):
def
_eval_type
(
t
,
globalns
,
localns
):
if
isinstance
(
t
,
TypingMeta
)
or
isinstance
(
t
,
_
ClassVar
):
if
isinstance
(
t
,
TypingMeta
)
or
isinstance
(
t
,
_
TypingBase
):
return
t
.
_eval_type
(
globalns
,
localns
)
else
:
return
t
...
...
@@ -306,7 +350,7 @@ def _type_check(arg, msg):
return
type
(
None
)
if
isinstance
(
arg
,
str
):
arg
=
_ForwardRef
(
arg
)
if
not
isinstance
(
arg
,
(
type
,
_Typ
eAlias
))
and
not
callable
(
arg
):
if
not
isinstance
(
arg
,
(
type
,
_Typ
ingBase
))
and
not
callable
(
arg
):
raise
TypeError
(
msg
+
" Got %.100r."
%
(
arg
,))
return
arg
...
...
@@ -328,23 +372,7 @@ def _type_repr(obj):
return
repr
(
obj
)
class
AnyMeta
(
TypingMeta
):
"""Metaclass for Any."""
def
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
False
):
self
=
super
().
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
_root
)
return
self
def
__instancecheck__
(
self
,
obj
):
raise
TypeError
(
"Any cannot be used with isinstance()."
)
def
__subclasscheck__
(
self
,
cls
):
if
not
isinstance
(
cls
,
type
):
return
super
().
__subclasscheck__
(
cls
)
# To TypeError.
return
True
class
Any
(
Final
,
metaclass
=
AnyMeta
,
_root
=
True
):
class
_Any
(
_FinalTypingBase
,
_root
=
True
):
"""Special type indicating an unconstrained type.
- Any object is an instance of Any.
...
...
@@ -354,8 +382,17 @@ class Any(Final, metaclass=AnyMeta, _root=True):
__slots__
=
()
def
__instancecheck__
(
self
,
obj
):
raise
TypeError
(
"Any cannot be used with isinstance()."
)
def
__subclasscheck__
(
self
,
cls
):
raise
TypeError
(
"Any cannot be used with issubclass()."
)
Any
=
_Any
(
_root
=
True
)
class
TypeVar
(
TypingMeta
,
metaclass
=
TypingMeta
,
_root
=
True
):
class
TypeVar
(
_TypingBase
,
_root
=
True
):
"""Type variable.
Usage::
...
...
@@ -400,9 +437,14 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
A.__constraints__ == (str, bytes)
"""
def
__new__
(
cls
,
name
,
*
constraints
,
bound
=
None
,
__slots__
=
(
'__name__'
,
'__bound__'
,
'__constraints__'
,
'__covariant__'
,
'__contravariant__'
)
def
__init__
(
self
,
name
,
*
constraints
,
bound
=
None
,
covariant
=
False
,
contravariant
=
False
):
self
=
super
().
__new__
(
cls
,
name
,
(
Final
,),
{},
_root
=
True
)
super
().
__init__
(
name
,
*
constraints
,
bound
=
bound
,
covariant
=
covariant
,
contravariant
=
contravariant
)
self
.
__name__
=
name
if
covariant
and
contravariant
:
raise
ValueError
(
"Bivariant types are not supported."
)
self
.
__covariant__
=
bool
(
covariant
)
...
...
@@ -417,7 +459,6 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
self
.
__bound__
=
_type_check
(
bound
,
"Bound must be a type."
)
else
:
self
.
__bound__
=
None
return
self
def
_get_type_vars
(
self
,
tvars
):
if
self
not
in
tvars
:
...
...
@@ -436,16 +477,7 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
raise
TypeError
(
"Type variables cannot be used with isinstance()."
)
def
__subclasscheck__
(
self
,
cls
):
# TODO: Make this raise TypeError too?
if
cls
is
self
:
return
True
if
cls
is
Any
:
return
True
if
self
.
__bound__
is
not
None
:
return
issubclass
(
cls
,
self
.
__bound__
)
if
self
.
__constraints__
:
return
any
(
issubclass
(
cls
,
c
)
for
c
in
self
.
__constraints__
)
return
True
raise
TypeError
(
"Type variables cannot be used with issubclass()."
)
# Some unconstrained type variables. These are used by the container types.
...
...
@@ -463,19 +495,85 @@ T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant.
AnyStr
=
TypeVar
(
'AnyStr'
,
bytes
,
str
)
class
UnionMeta
(
TypingMeta
):
"""Metaclass for Union."""
def
_tp_cache
(
func
):
cached
=
functools
.
lru_cache
()(
func
)
@
functools
.
wraps
(
func
)
def
inner
(
*
args
,
**
kwds
):
try
:
return
cached
(
*
args
,
**
kwds
)
except
TypeError
:
pass
# Do not duplicate real errors.
return
func
(
*
args
,
**
kwds
)
return
inner
class
_Union
(
_FinalTypingBase
,
_root
=
True
):
"""Union type; Union[X, Y] means either X or Y.
To define a union, use e.g. Union[int, str]. Details:
- The arguments must be types and there must be at least one.
- None as an argument is a special case and is replaced by
type(None).
- Unions of unions are flattened, e.g.::
Union[Union[int, str], float] == Union[int, str, float]
- Unions of a single argument vanish, e.g.::
Union[int] == int # The constructor actually returns int
- Redundant arguments are skipped, e.g.::
Union[int, str, int] == Union[int, str]
- When comparing unions, the argument order is ignored, e.g.::
def
__new__
(
cls
,
name
,
bases
,
namespace
,
parameters
=
None
,
_root
=
False
):
Union[int, str] == Union[str, int]
- When two arguments have a subclass relationship, the least
derived argument is kept, e.g.::
class Employee: pass
class Manager(Employee): pass
Union[int, Employee, Manager] == Union[int, Employee]
Union[Manager, int, Employee] == Union[int, Employee]
Union[Employee, Manager] == Employee
- Corollary: if Any is present it is the sole survivor, e.g.::
Union[int, Any] == Any
- Similar for object::
Union[int, object] == object
- To cut a tie: Union[object, Any] == Union[Any, object] == Any.
- You cannot subclass or instantiate a union.
- You cannot write Union[X][Y] (what would it mean?).
- You can use Optional[X] as a shorthand for Union[X, None].
"""
__slots__
=
(
'__union_params__'
,
'__union_set_params__'
)
def
__new__
(
cls
,
parameters
=
None
,
*
args
,
_root
=
False
):
self
=
super
().
__new__
(
cls
,
parameters
,
*
args
,
_root
=
_root
)
if
parameters
is
None
:
return
super
().
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
_root
)
self
.
__union_params__
=
None
self
.
__union_set_params__
=
None
return
self
if
not
isinstance
(
parameters
,
tuple
):
raise
TypeError
(
"Expected parameters=<tuple>"
)
# Flatten out Union[Union[...], ...] and type-check non-Union args.
params
=
[]
msg
=
"Union[arg, ...]: each arg must be a type."
for
p
in
parameters
:
if
isinstance
(
p
,
UnionMeta
):
if
isinstance
(
p
,
_Union
):
params
.
extend
(
p
.
__union_params__
)
else
:
params
.
append
(
_type_check
(
p
,
msg
))
...
...
@@ -499,22 +597,16 @@ class UnionMeta(TypingMeta):
for
t1
in
params
:
if
t1
is
Any
:
return
Any
if
isinstance
(
t1
,
TypeVar
):
continue
if
isinstance
(
t1
,
_TypeAlias
):
# _TypeAlias is not a real class.
continue
if
not
isinstance
(
t1
,
type
):
assert
callable
(
t1
)
# A callable might sneak through.
continue
if
any
(
isinstance
(
t2
,
type
)
and
issubclass
(
t1
,
t2
)
for
t2
in
all_params
-
{
t1
}
if
not
isinstance
(
t2
,
TypeVar
)):
for
t2
in
all_params
-
{
t1
}
if
not
(
isinstance
(
t2
,
GenericMeta
)
and
t2
.
__origin__
is
not
None
)):
all_params
.
remove
(
t1
)
# It's not a union if there's only one type left.
if
len
(
all_params
)
==
1
:
return
all_params
.
pop
()
# Create a new class with these params.
self
=
super
().
__new__
(
cls
,
name
,
bases
,
{},
_root
=
True
)
self
.
__union_params__
=
tuple
(
t
for
t
in
params
if
t
in
all_params
)
self
.
__union_set_params__
=
frozenset
(
self
.
__union_params__
)
return
self
...
...
@@ -525,8 +617,7 @@ class UnionMeta(TypingMeta):
if
p
==
self
.
__union_params__
:
return
self
else
:
return
self
.
__class__
(
self
.
__name__
,
self
.
__bases__
,
{},
p
,
_root
=
True
)
return
self
.
__class__
(
p
,
_root
=
True
)
def
_get_type_vars
(
self
,
tvars
):
if
self
.
__union_params__
:
...
...
@@ -539,6 +630,7 @@ class UnionMeta(TypingMeta):
for
t
in
self
.
__union_params__
))
return
r
@
_tp_cache
def
__getitem__
(
self
,
parameters
):
if
self
.
__union_params__
is
not
None
:
raise
TypeError
(
...
...
@@ -547,11 +639,10 @@ class UnionMeta(TypingMeta):
raise
TypeError
(
"Cannot take a Union of no types."
)
if
not
isinstance
(
parameters
,
tuple
):
parameters
=
(
parameters
,)
return
self
.
__class__
(
self
.
__name__
,
self
.
__bases__
,
dict
(
self
.
__dict__
),
parameters
,
_root
=
True
)
return
self
.
__class__
(
parameters
,
_root
=
True
)
def
__eq__
(
self
,
other
):
if
not
isinstance
(
other
,
UnionMeta
):
if
not
isinstance
(
other
,
_Union
):
return
NotImplemented
return
self
.
__union_set_params__
==
other
.
__union_set_params__
...
...
@@ -562,110 +653,45 @@ class UnionMeta(TypingMeta):
raise
TypeError
(
"Unions cannot be used with isinstance()."
)
def
__subclasscheck__
(
self
,
cls
):
if
cls
is
Any
:
return
True
if
self
.
__union_params__
is
None
:
return
isinstance
(
cls
,
UnionMeta
)
elif
isinstance
(
cls
,
UnionMeta
):
if
cls
.
__union_params__
is
None
:
return
False
return
all
(
issubclass
(
c
,
self
)
for
c
in
(
cls
.
__union_params__
))
elif
isinstance
(
cls
,
TypeVar
):
if
cls
in
self
.
__union_params__
:
return
True
if
cls
.
__constraints__
:
return
issubclass
(
Union
[
cls
.
__constraints__
],
self
)
return
False
else
:
return
any
(
issubclass
(
cls
,
t
)
for
t
in
self
.
__union_params__
)
raise
TypeError
(
"Unions cannot be used with issubclass()."
)
class
Union
(
Final
,
metaclass
=
UnionMeta
,
_root
=
True
):
"""Union type; Union[X, Y] means either X or Y.
To define a union, use e.g. Union[int, str]. Details:
- The arguments must be types and there must be at least one.
- None as an argument is a special case and is replaced by
type(None).
- Unions of unions are flattened, e.g.::
Union[Union[int, str], float] == Union[int, str, float]
- Unions of a single argument vanish, e.g.::
Union[int] == int # The constructor actually returns int
- Redundant arguments are skipped, e.g.::
Union[int, str, int] == Union[int, str]
- When comparing unions, the argument order is ignored, e.g.::
Union[int, str] == Union[str, int]
- When two arguments have a subclass relationship, the least
derived argument is kept, e.g.::
class Employee: pass
class Manager(Employee): pass
Union[int, Employee, Manager] == Union[int, Employee]
Union[Manager, int, Employee] == Union[int, Employee]
Union[Employee, Manager] == Employee
- Corollary: if Any is present it is the sole survivor, e.g.::
Union[int, Any] == Any
Union
=
_Union
(
_root
=
True
)
- Similar for object::
Union[int, object] == object
- To cut a tie: Union[object, Any] == Union[Any, object] == Any.
- You cannot subclass or instantiate a union.
- You cannot write Union[X][Y] (what would it mean?).
class
_Optional
(
_FinalTypingBase
,
_root
=
True
):
"""Optional type.
- You can use Optional[X] as a shorthand for Union[X, None
].
Optional[X] is equivalent to Union[X, type(None)
].
"""
# Unsubscripted Union type has params set to None.
__union_params__
=
None
__union_set_params__
=
None
class
OptionalMeta
(
TypingMeta
):
"""Metaclass for Optional."""
def
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
False
):
return
super
().
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
_root
)
__slots__
=
()
@
_tp_cache
def
__getitem__
(
self
,
arg
):
arg
=
_type_check
(
arg
,
"Optional[t] requires a single type."
)
return
Union
[
arg
,
type
(
None
)]
class
Optional
(
Final
,
metaclass
=
OptionalMeta
,
_root
=
True
):
"""Optional type.
Optional
=
_Optional
(
_root
=
True
)
Optional[X] is equivalent to Union[X, type(None)].
"""
__slots__
=
()
class
_Tuple
(
_FinalTypingBase
,
_root
=
True
):
"""Tuple type; Tuple[X, Y] is the cross-product type of X and Y.
Example: Tuple[T1, T2] is a tuple of two elements corresponding
to type variables T1 and T2. Tuple[int, float, str] is a tuple
of an int, a float and a string.
To specify a variable-length tuple of homogeneous type, use Tuple[T, ...].
"""
class
TupleMeta
(
TypingMeta
):
"""Metaclass for Tuple."""
__slots__
=
(
'__tuple_params__'
,
'__tuple_use_ellipsis__'
)
def
__
new__
(
cls
,
name
,
bases
,
namespace
,
parameters
=
None
,
def
__
init__
(
self
,
parameters
=
None
,
use_ellipsis
=
False
,
_root
=
False
):
self
=
super
().
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
_root
)
self
.
__tuple_params__
=
parameters
self
.
__tuple_use_ellipsis__
=
use_ellipsis
return
self
def
_get_type_vars
(
self
,
tvars
):
if
self
.
__tuple_params__
:
...
...
@@ -679,8 +705,7 @@ class TupleMeta(TypingMeta):
if
p
==
self
.
__tuple_params__
:
return
self
else
:
return
self
.
__class__
(
self
.
__name__
,
self
.
__bases__
,
{},
p
,
_root
=
True
)
return
self
.
__class__
(
p
,
_root
=
True
)
def
__repr__
(
self
):
r
=
super
().
__repr__
()
...
...
@@ -694,6 +719,7 @@ class TupleMeta(TypingMeta):
', '
.
join
(
params
))
return
r
@
_tp_cache
def
__getitem__
(
self
,
parameters
):
if
self
.
__tuple_params__
is
not
None
:
raise
TypeError
(
"Cannot re-parameterize %r"
%
(
self
,))
...
...
@@ -707,64 +733,50 @@ class TupleMeta(TypingMeta):
use_ellipsis
=
False
msg
=
"Tuple[t0, t1, ...]: each t must be a type."
parameters
=
tuple
(
_type_check
(
p
,
msg
)
for
p
in
parameters
)
return
self
.
__class__
(
self
.
__name__
,
self
.
__bases__
,
dict
(
self
.
__dict__
),
parameters
,
return
self
.
__class__
(
parameters
,
use_ellipsis
=
use_ellipsis
,
_root
=
True
)
def
__eq__
(
self
,
other
):
if
not
isinstance
(
other
,
TupleMeta
):
if
not
isinstance
(
other
,
_Tuple
):
return
NotImplemented
return
(
self
.
__tuple_params__
==
other
.
__tuple_params__
and
self
.
__tuple_use_ellipsis__
==
other
.
__tuple_use_ellipsis__
)
def
__hash__
(
self
):
return
hash
(
self
.
__tuple_params__
)
return
hash
(
(
self
.
__tuple_params__
,
self
.
__tuple_use_ellipsis__
)
)
def
__instancecheck__
(
self
,
obj
):
raise
TypeError
(
"Tuples cannot be used with isinstance()."
)
if
self
.
__tuple_params__
==
None
:
return
isinstance
(
obj
,
tuple
)
raise
TypeError
(
"Parameterized Tuple cannot be used "
"with isinstance()."
)
def
__subclasscheck__
(
self
,
cls
):
if
cls
is
Any
:
return
True
if
not
isinstance
(
cls
,
type
):
return
super
().
__subclasscheck__
(
cls
)
# To TypeError.
if
issubclass
(
cls
,
tuple
):
return
True
# Special case.
if
not
isinstance
(
cls
,
TupleMeta
):
return
super
().
__subclasscheck__
(
cls
)
# False.
if
self
.
__tuple_params__
is
None
:
return
True
if
cls
.
__tuple_params__
is
None
:
return
False
# ???
if
cls
.
__tuple_use_ellipsis__
!=
self
.
__tuple_use_ellipsis__
:
return
False
# Covariance.
return
(
len
(
self
.
__tuple_params__
)
==
len
(
cls
.
__tuple_params__
)
and
all
(
issubclass
(
x
,
p
)
for
x
,
p
in
zip
(
cls
.
__tuple_params__
,
self
.
__tuple_params__
)))
class
Tuple
(
Final
,
metaclass
=
TupleMeta
,
_root
=
True
):
"""Tuple type; Tuple[X, Y] is the cross-product type of X and Y.
if
self
.
__tuple_params__
==
None
:
return
issubclass
(
cls
,
tuple
)
raise
TypeError
(
"Parameterized Tuple cannot be used "
"with issubclass()."
)
Example: Tuple[T1, T2] is a tuple of two elements corresponding
to type variables T1 and T2. Tuple[int, float, str] is a tuple
of an int, a float and a string.
To specify a variable-length tuple of homogeneous type, use Sequence[T].
"""
Tuple
=
_Tuple
(
_root
=
True
)
__slots__
=
()
class
_Callable
(
_FinalTypingBase
,
_root
=
True
):
"""Callable type; Callable[[int], str] is a function of (int) -> str.
class
CallableMeta
(
TypingMeta
):
"""Metaclass for Callable."""
The subscription syntax must always be used with exactly two
values: the argument list and the return type. The argument list
must be a list of types; the return type must be a single type.
def
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
False
,
args
=
None
,
result
=
None
):
There is no syntax to indicate optional or keyword arguments,
such function types are rarely used as callback types.
"""
__slots__
=
(
'__args__'
,
'__result__'
)
def
__init__
(
self
,
args
=
None
,
result
=
None
,
_root
=
False
):
if
args
is
None
and
result
is
None
:
pass
# Must be 'class Callable'.
pass
else
:
if
args
is
not
Ellipsis
:
if
not
isinstance
(
args
,
list
):
...
...
@@ -775,10 +787,8 @@ class CallableMeta(TypingMeta):
args
=
tuple
(
_type_check
(
arg
,
msg
)
for
arg
in
args
)
msg
=
"Callable[args, result]: result must be a type."
result
=
_type_check
(
result
,
msg
)
self
=
super
().
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
_root
)
self
.
__args__
=
args
self
.
__result__
=
result
return
self
def
_get_type_vars
(
self
,
tvars
):
if
self
.
__args__
and
self
.
__args__
is
not
Ellipsis
:
...
...
@@ -795,8 +805,7 @@ class CallableMeta(TypingMeta):
if
args
==
self
.
__args__
and
result
==
self
.
__result__
:
return
self
else
:
return
self
.
__class__
(
self
.
__name__
,
self
.
__bases__
,
{},
args
=
args
,
result
=
result
,
_root
=
True
)
return
self
.
__class__
(
args
,
result
,
_root
=
True
)
def
__repr__
(
self
):
r
=
super
().
__repr__
()
...
...
@@ -816,12 +825,10 @@ class CallableMeta(TypingMeta):
raise
TypeError
(
"Callable must be used as Callable[[arg, ...], result]."
)
args
,
result
=
parameters
return
self
.
__class__
(
self
.
__name__
,
self
.
__bases__
,
dict
(
self
.
__dict__
),
_root
=
True
,
args
=
args
,
result
=
result
)
return
self
.
__class__
(
args
,
result
,
_root
=
True
)
def
__eq__
(
self
,
other
):
if
not
isinstance
(
other
,
CallableMeta
):
if
not
isinstance
(
other
,
_Callable
):
return
NotImplemented
return
(
self
.
__args__
==
other
.
__args__
and
self
.
__result__
==
other
.
__result__
)
...
...
@@ -836,31 +843,18 @@ class CallableMeta(TypingMeta):
if
self
.
__args__
is
None
and
self
.
__result__
is
None
:
return
isinstance
(
obj
,
collections_abc
.
Callable
)
else
:
raise
TypeError
(
"Callable[] cannot be used with isinstance()."
)
raise
TypeError
(
"Parameterized Callable cannot be used "
"with isinstance()."
)
def
__subclasscheck__
(
self
,
cls
):
if
cls
is
Any
:
return
True
if
not
isinstance
(
cls
,
CallableMeta
):
return
super
().
__subclasscheck__
(
cls
)
if
self
.
__args__
is
None
and
self
.
__result__
is
None
:
return
True
# We're not doing covariance or contravariance -- this is *invariance*.
return
self
==
cls
class
Callable
(
Final
,
metaclass
=
CallableMeta
,
_root
=
True
):
"""Callable type; Callable[[int], str] is a function of (int) -> str.
The subscription syntax must always be used with exactly two
values: the argument list and the return type. The argument list
must be a list of types; the return type must be a single type.
return
issubclass
(
cls
,
collections_abc
.
Callable
)
else
:
raise
TypeError
(
"Parameterized Callable cannot be used "
"with issubclass()."
)
There is no syntax to indicate optional or keyword arguments,
such function types are rarely used as callback types.
"""
__slots__
=
(
)
Callable
=
_Callable
(
_root
=
True
)
def
_gorg
(
a
):
...
...
@@ -985,6 +979,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
def
__hash__
(
self
):
return
hash
((
self
.
__name__
,
self
.
__parameters__
))
@
_tp_cache
def
__getitem__
(
self
,
params
):
if
not
isinstance
(
params
,
tuple
):
params
=
(
params
,)
...
...
@@ -1040,44 +1035,18 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
return
self
.
__subclasscheck__
(
instance
.
__class__
)
def
__subclasscheck__
(
self
,
cls
):
if
cls
is
Any
:
return
True
if
isinstance
(
cls
,
GenericMeta
):
# For a covariant class C(Generic[T]),
# 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
.
__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__
:
# Covariant -- p_cls must be a subclass of p_self.
if
not
issubclass
(
p_cls
,
p_self
):
break
elif
p_origin
.
__contravariant__
:
# Contravariant. I think it's the opposite. :-)
if
not
issubclass
(
p_self
,
p_cls
):
break
else
:
# Invariant -- p_cls and p_self must equal.
if
p_self
!=
p_cls
:
break
else
:
# If the origin's parameter is not a typevar,
# insist on invariance.
if
p_self
!=
p_cls
:
break
else
:
return
True
# If we break out of the loop, the superclass gets a chance.
if
self
is
Generic
:
raise
TypeError
(
"Class %r cannot be used with class "
"or instance checks"
%
self
)
if
(
self
.
__origin__
is
not
None
and
sys
.
_getframe
(
1
).
f_globals
[
'__name__'
]
!=
'abc'
):
raise
TypeError
(
"Parameterized generics cannot be used with class "
"or instance checks"
)
if
super
().
__subclasscheck__
(
cls
):
return
True
if
self
.
__extra__
is
None
or
isinstance
(
cls
,
GenericMeta
)
:
return
False
return
issubclass
(
cls
,
self
.
__extra__
)
if
self
.
__extra__
is
not
None
:
return
issubclass
(
cls
,
self
.
__extra__
)
return
False
# Prevent checks for Generic to crash when defining Generic.
...
...
@@ -1117,7 +1086,7 @@ class Generic(metaclass=GenericMeta):
return
obj
class
_ClassVar
(
metaclass
=
TypingMeta
,
_root
=
True
):
class
_ClassVar
(
_FinalTypingBase
,
_root
=
True
):
"""Special type construct to mark class variables.
An annotation wrapped in ClassVar indicates that a given
...
...
@@ -1134,36 +1103,35 @@ class _ClassVar(metaclass=TypingMeta, _root=True):
be used with isinstance() or issubclass().
"""
def
__init__
(
self
,
tp
=
None
,
_root
=
False
):
cls
=
type
(
self
)
if
_root
:
self
.
__type__
=
tp
else
:
raise
TypeError
(
'Cannot initialize {}'
.
format
(
cls
.
__name__
[
1
:]))
__slots__
=
(
'__type__'
,)
def
__init__
(
self
,
tp
=
None
,
**
kwds
):
self
.
__type__
=
tp
def
__getitem__
(
self
,
item
):
cls
=
type
(
self
)
if
self
.
__type__
is
None
:
return
cls
(
_type_check
(
item
,
'{} accepts only
types
.'
.
format
(
cls
.
__name__
[
1
:])),
'{} accepts only
single type
.'
.
format
(
cls
.
__name__
[
1
:])),
_root
=
True
)
raise
TypeError
(
'{} cannot be further subscripted'
.
format
(
cls
.
__name__
[
1
:]))
def
_eval_type
(
self
,
globalns
,
localns
):
return
type
(
self
)(
_eval_type
(
self
.
__type__
,
globalns
,
localns
),
_root
=
True
)
new_tp
=
_eval_type
(
self
.
__type__
,
globalns
,
localns
)
if
new_tp
==
self
.
__type__
:
return
self
return
type
(
self
)(
new_tp
,
_root
=
True
)
def
_get_type_vars
(
self
,
tvars
):
if
self
.
__type__
:
_get_type_vars
(
self
.
__type__
,
tvars
)
def
__repr__
(
self
):
cls
=
type
(
self
)
if
not
self
.
__type__
:
return
'{}.{}'
.
format
(
cls
.
__module__
,
cls
.
__name__
[
1
:])
return
'{}.{}[{}]'
.
format
(
cls
.
__module__
,
cls
.
__name__
[
1
:],
_type_repr
(
self
.
__type__
))
r
=
super
().
__repr__
()
if
self
.
__type__
is
not
None
:
r
+=
'[{}]'
.
format
(
_type_repr
(
self
.
__type__
))
return
r
def
__hash__
(
self
):
return
hash
((
type
(
self
).
__name__
,
self
.
__type__
))
...
...
@@ -1614,52 +1582,52 @@ if hasattr(collections_abc, 'Collection'):
if
hasattr
(
collections_abc
,
'Collection'
):
class
AbstractSet
(
Collection
[
T_co
],
extra
=
collections_abc
.
Set
):
pass
__slots__
=
()
else
:
class
AbstractSet
(
Sized
,
Iterable
[
T_co
],
Container
[
T_co
],
extra
=
collections_abc
.
Set
):
pass
__slots__
=
()
class
MutableSet
(
AbstractSet
[
T
],
extra
=
collections_abc
.
MutableSet
):
pass
__slots__
=
()
# NOTE: It is only covariant in the value type.
if
hasattr
(
collections_abc
,
'Collection'
):
class
Mapping
(
Collection
[
KT
],
Generic
[
KT
,
VT_co
],
extra
=
collections_abc
.
Mapping
):
pass
__slots__
=
()
else
:
class
Mapping
(
Sized
,
Iterable
[
KT
],
Container
[
KT
],
Generic
[
KT
,
VT_co
],
extra
=
collections_abc
.
Mapping
):
pass
__slots__
=
()
class
MutableMapping
(
Mapping
[
KT
,
VT
],
extra
=
collections_abc
.
MutableMapping
):
pass
__slots__
=
()
if
hasattr
(
collections_abc
,
'Reversible'
):
if
hasattr
(
collections_abc
,
'Collection'
):
class
Sequence
(
Reversible
[
T_co
],
Collection
[
T_co
],
extra
=
collections_abc
.
Sequence
):
pass
__slots__
=
()
else
:
class
Sequence
(
Sized
,
Reversible
[
T_co
],
Container
[
T_co
],
extra
=
collections_abc
.
Sequence
):
pass
__slots__
=
()
else
:
class
Sequence
(
Sized
,
Iterable
[
T_co
],
Container
[
T_co
],
extra
=
collections_abc
.
Sequence
):
pass
__slots__
=
()
class
MutableSequence
(
Sequence
[
T
],
extra
=
collections_abc
.
MutableSequence
):
pass
__slots__
=
()
class
ByteString
(
Sequence
[
int
],
extra
=
collections_abc
.
ByteString
):
pass
__slots__
=
()
ByteString
.
register
(
type
(
memoryview
(
b''
)))
...
...
@@ -1667,6 +1635,8 @@ ByteString.register(type(memoryview(b'')))
class
List
(
list
,
MutableSequence
[
T
],
extra
=
list
):
__slots__
=
()
def
__new__
(
cls
,
*
args
,
**
kwds
):
if
_geqv
(
cls
,
List
):
raise
TypeError
(
"Type List cannot be instantiated; "
...
...
@@ -1676,6 +1646,8 @@ class List(list, MutableSequence[T], extra=list):
class
Set
(
set
,
MutableSet
[
T
],
extra
=
set
):
__slots__
=
()
def
__new__
(
cls
,
*
args
,
**
kwds
):
if
_geqv
(
cls
,
Set
):
raise
TypeError
(
"Type Set cannot be instantiated; "
...
...
@@ -1683,22 +1655,7 @@ class Set(set, MutableSet[T], extra=set):
return
set
.
__new__
(
cls
,
*
args
,
**
kwds
)
class
_FrozenSetMeta
(
GenericMeta
):
"""This metaclass ensures set is not a subclass of FrozenSet.
Without this metaclass, set would be considered a subclass of
FrozenSet, because FrozenSet.__extra__ is collections.abc.Set, and
set is a subclass of that.
"""
def
__subclasscheck__
(
self
,
cls
):
if
issubclass
(
cls
,
Set
):
return
False
return
super
().
__subclasscheck__
(
cls
)
class
FrozenSet
(
frozenset
,
AbstractSet
[
T_co
],
metaclass
=
_FrozenSetMeta
,
extra
=
frozenset
):
class
FrozenSet
(
frozenset
,
AbstractSet
[
T_co
],
extra
=
frozenset
):
__slots__
=
()
def
__new__
(
cls
,
*
args
,
**
kwds
):
...
...
@@ -1709,23 +1666,23 @@ class FrozenSet(frozenset, AbstractSet[T_co], metaclass=_FrozenSetMeta,
class
MappingView
(
Sized
,
Iterable
[
T_co
],
extra
=
collections_abc
.
MappingView
):
pass
__slots__
=
()
class
KeysView
(
MappingView
[
KT
],
AbstractSet
[
KT
],
extra
=
collections_abc
.
KeysView
):
pass
__slots__
=
()
class
ItemsView
(
MappingView
[
Tuple
[
KT
,
VT_co
]],
AbstractSet
[
Tuple
[
KT
,
VT_co
]],
Generic
[
KT
,
VT_co
],
extra
=
collections_abc
.
ItemsView
):
pass
__slots__
=
()
class
ValuesView
(
MappingView
[
VT_co
],
extra
=
collections_abc
.
ValuesView
):
pass
__slots__
=
()
if
hasattr
(
contextlib
,
'AbstractContextManager'
):
...
...
@@ -1736,6 +1693,8 @@ if hasattr(contextlib, 'AbstractContextManager'):
class
Dict
(
dict
,
MutableMapping
[
KT
,
VT
],
extra
=
dict
):
__slots__
=
()
def
__new__
(
cls
,
*
args
,
**
kwds
):
if
_geqv
(
cls
,
Dict
):
raise
TypeError
(
"Type Dict cannot be instantiated; "
...
...
@@ -1745,6 +1704,8 @@ class Dict(dict, MutableMapping[KT, VT], extra=dict):
class
DefaultDict
(
collections
.
defaultdict
,
MutableMapping
[
KT
,
VT
],
extra
=
collections
.
defaultdict
):
__slots__
=
()
def
__new__
(
cls
,
*
args
,
**
kwds
):
if
_geqv
(
cls
,
DefaultDict
):
raise
TypeError
(
"Type DefaultDict cannot be instantiated; "
...
...
@@ -1800,6 +1761,8 @@ class Type(Generic[CT_co], extra=type):
At this point the type checker knows that joe has type BasicUser.
"""
__slots__
=
()
def
_make_nmtuple
(
name
,
types
):
nm_tpl
=
collections
.
namedtuple
(
name
,
[
n
for
n
,
t
in
types
])
...
...
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