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
83ec302e
Commit
83ec302e
authored
Jan 17, 2017
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #28556: merge 5 more typing changes from upstream (#340, #344, #348, #349, #350)
parent
e741e4f8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
76 additions
and
12 deletions
+76
-12
Lib/test/test_typing.py
Lib/test/test_typing.py
+33
-4
Lib/typing.py
Lib/typing.py
+43
-8
No files found.
Lib/test/test_typing.py
View file @
83ec302e
...
...
@@ -12,7 +12,7 @@ from typing import T, KT, VT # Not in __all__.
from
typing
import
Union
,
Optional
from
typing
import
Tuple
,
List
,
MutableMapping
from
typing
import
Callable
from
typing
import
Generic
,
ClassVar
from
typing
import
Generic
,
ClassVar
,
GenericMeta
from
typing
import
cast
from
typing
import
get_type_hints
from
typing
import
no_type_check
,
no_type_check_decorator
...
...
@@ -23,6 +23,7 @@ from typing import IO, TextIO, BinaryIO
from
typing
import
Pattern
,
Match
import
abc
import
typing
import
weakref
try
:
import
collections.abc
as
collections_abc
except
ImportError
:
...
...
@@ -281,6 +282,15 @@ class UnionTests(BaseTestCase):
self
.
assertFalse
(
Union
[
str
,
typing
.
Iterable
[
int
]]
==
typing
.
Iterable
[
int
])
self
.
assertTrue
(
Union
[
str
,
typing
.
Iterable
]
==
typing
.
Iterable
)
def
test_union_compare_other
(
self
):
self
.
assertNotEqual
(
Union
,
object
)
self
.
assertNotEqual
(
Union
,
Any
)
self
.
assertNotEqual
(
ClassVar
,
Union
)
self
.
assertNotEqual
(
Optional
,
Union
)
self
.
assertNotEqual
([
None
],
Optional
)
self
.
assertNotEqual
(
Optional
,
typing
.
Mapping
)
self
.
assertNotEqual
(
Optional
[
typing
.
MutableMapping
],
Union
)
def
test_optional
(
self
):
o
=
Optional
[
int
]
u
=
Union
[
int
,
None
]
...
...
@@ -718,6 +728,12 @@ class GenericTests(BaseTestCase):
self
.
assertEqual
(
C
.
__orig_bases__
,
(
List
[
T
][
U
][
V
],))
self
.
assertEqual
(
D
.
__orig_bases__
,
(
C
,
List
[
T
][
U
][
V
]))
def
test_subscript_meta
(
self
):
T
=
TypeVar
(
'T'
)
self
.
assertEqual
(
Type
[
GenericMeta
],
Type
[
GenericMeta
])
self
.
assertEqual
(
Union
[
T
,
int
][
GenericMeta
],
Union
[
GenericMeta
,
int
])
self
.
assertEqual
(
Callable
[...,
GenericMeta
].
__args__
,
(
Ellipsis
,
GenericMeta
))
def
test_extended_generic_rules_eq
(
self
):
T
=
TypeVar
(
'T'
)
U
=
TypeVar
(
'U'
)
...
...
@@ -896,6 +912,14 @@ class GenericTests(BaseTestCase):
self
.
assertEqual
(
t
,
copy
(
t
))
self
.
assertEqual
(
t
,
deepcopy
(
t
))
def
test_weakref_all
(
self
):
T
=
TypeVar
(
'T'
)
things
=
[
Any
,
Union
[
T
,
int
],
Callable
[...,
T
],
Tuple
[
Any
,
Any
],
Optional
[
List
[
int
]],
typing
.
Mapping
[
int
,
str
],
typing
.
re
.
Match
[
bytes
],
typing
.
Iterable
[
'whatever'
]]
for
t
in
things
:
self
.
assertEqual
(
weakref
.
ref
(
t
)(),
t
)
def
test_parameterized_slots
(
self
):
T
=
TypeVar
(
'T'
)
class
C
(
Generic
[
T
]):
...
...
@@ -1918,7 +1942,9 @@ class NamedTupleTests(BaseTestCase):
self
.
assertEqual
(
jim
.
id
,
1
)
self
.
assertEqual
(
Emp
.
__name__
,
'Emp'
)
self
.
assertEqual
(
Emp
.
_fields
,
(
'name'
,
'id'
))
self
.
assertEqual
(
Emp
.
_field_types
,
dict
(
name
=
str
,
id
=
int
))
self
.
assertEqual
(
Emp
.
__annotations__
,
collections
.
OrderedDict
([(
'name'
,
str
),
(
'id'
,
int
)]))
self
.
assertIs
(
Emp
.
_field_types
,
Emp
.
__annotations__
)
@
skipUnless
(
PY36
,
'Python 3.6 required'
)
def
test_annotation_usage
(
self
):
...
...
@@ -1929,7 +1955,9 @@ class NamedTupleTests(BaseTestCase):
self
.
assertEqual
(
tim
.
cool
,
9000
)
self
.
assertEqual
(
CoolEmployee
.
__name__
,
'CoolEmployee'
)
self
.
assertEqual
(
CoolEmployee
.
_fields
,
(
'name'
,
'cool'
))
self
.
assertEqual
(
CoolEmployee
.
_field_types
,
dict
(
name
=
str
,
cool
=
int
))
self
.
assertEqual
(
CoolEmployee
.
__annotations__
,
collections
.
OrderedDict
(
name
=
str
,
cool
=
int
))
self
.
assertIs
(
CoolEmployee
.
_field_types
,
CoolEmployee
.
__annotations__
)
@
skipUnless
(
PY36
,
'Python 3.6 required'
)
def
test_namedtuple_keyword_usage
(
self
):
...
...
@@ -1939,7 +1967,8 @@ class NamedTupleTests(BaseTestCase):
self
.
assertEqual
(
nick
.
name
,
'Nick'
)
self
.
assertEqual
(
LocalEmployee
.
__name__
,
'LocalEmployee'
)
self
.
assertEqual
(
LocalEmployee
.
_fields
,
(
'name'
,
'age'
))
self
.
assertEqual
(
LocalEmployee
.
_field_types
,
dict
(
name
=
str
,
age
=
int
))
self
.
assertEqual
(
LocalEmployee
.
__annotations__
,
dict
(
name
=
str
,
age
=
int
))
self
.
assertIs
(
LocalEmployee
.
_field_types
,
LocalEmployee
.
__annotations__
)
with
self
.
assertRaises
(
TypeError
):
NamedTuple
(
'Name'
,
[(
'x'
,
int
)],
y
=
str
)
with
self
.
assertRaises
(
TypeError
):
...
...
Lib/typing.py
View file @
83ec302e
...
...
@@ -27,6 +27,8 @@ __all__ = [
# ABCs (from collections.abc).
'AbstractSet'
,
# collections.abc.Set.
'GenericMeta'
,
# subclass of abc.ABCMeta and a metaclass
# for 'Generic' and ABCs below.
'ByteString'
,
'Container'
,
'Hashable'
,
...
...
@@ -145,7 +147,7 @@ class TypingMeta(type):
class
_TypingBase
(
metaclass
=
TypingMeta
,
_root
=
True
):
"""Internal indicator of special typing constructs."""
__slots__
=
()
__slots__
=
(
'__weakref__'
,
)
def
__init__
(
self
,
*
args
,
**
kwds
):
pass
...
...
@@ -514,7 +516,7 @@ def _replace_arg(arg, tvars, args):
if
tvars
is
None
:
tvars
=
[]
if
hasattr
(
arg
,
'_subs_tree'
):
if
hasattr
(
arg
,
'_subs_tree'
)
and
isinstance
(
arg
,
(
GenericMeta
,
_TypingBase
))
:
return
arg
.
_subs_tree
(
tvars
,
args
)
if
isinstance
(
arg
,
TypeVar
):
for
i
,
tvar
in
enumerate
(
tvars
):
...
...
@@ -523,6 +525,16 @@ def _replace_arg(arg, tvars, args):
return
arg
# Special typing constructs Union, Optional, Generic, Callable and Tuple
# use three special attributes for internal bookkeeping of generic types:
# * __parameters__ is a tuple of unique free type parameters of a generic
# type, for example, Dict[T, T].__parameters__ == (T,);
# * __origin__ keeps a reference to a type that was subscripted,
# e.g., Union[T, int].__origin__ == Union;
# * __args__ is a tuple of all arguments used in subscripting,
# e.g., Dict[T, int].__args__ == (T, int).
def
_subs_tree
(
cls
,
tvars
=
None
,
args
=
None
):
"""An internal helper function: calculate substitution tree
for generic cls after replacing its type parameters with
...
...
@@ -757,9 +769,12 @@ class _Union(_FinalTypingBase, _root=True):
return
(
Union
,)
+
tree_args
def
__eq__
(
self
,
other
):
if
not
isinstance
(
other
,
_Union
):
if
isinstance
(
other
,
_Union
):
return
self
.
__tree_hash__
==
other
.
__tree_hash__
elif
self
is
not
Union
:
return
self
.
_subs_tree
()
==
other
return
self
.
__tree_hash__
==
other
.
__tree_hash__
else
:
return
self
is
other
def
__hash__
(
self
):
return
self
.
__tree_hash__
...
...
@@ -883,10 +898,26 @@ def _no_slots_copy(dct):
class
GenericMeta
(
TypingMeta
,
abc
.
ABCMeta
):
"""Metaclass for generic types."""
"""Metaclass for generic types.
This is a metaclass for typing.Generic and generic ABCs defined in
typing module. User defined subclasses of GenericMeta can override
__new__ and invoke super().__new__. Note that GenericMeta.__new__
has strict rules on what is allowed in its bases argument:
* plain Generic is disallowed in bases;
* Generic[...] should appear in bases at most once;
* if Generic[...] is present, then it should list all type variables
that appear in other bases.
In addition, type of all generic bases is erased, e.g., C[int] is
stripped to plain C.
"""
def
__new__
(
cls
,
name
,
bases
,
namespace
,
tvars
=
None
,
args
=
None
,
origin
=
None
,
extra
=
None
,
orig_bases
=
None
):
"""Create a new generic class. GenericMeta.__new__ accepts
keyword arguments that are used for internal bookkeeping, therefore
an override should pass unused keyword arguments to super().
"""
if
tvars
is
not
None
:
# Called from __getitem__() below.
assert
origin
is
not
None
...
...
@@ -1906,7 +1937,9 @@ def _make_nmtuple(name, types):
msg
=
"NamedTuple('Name', [(f0, t0), (f1, t1), ...]); each t must be a type"
types
=
[(
n
,
_type_check
(
t
,
msg
))
for
n
,
t
in
types
]
nm_tpl
=
collections
.
namedtuple
(
name
,
[
n
for
n
,
t
in
types
])
nm_tpl
.
_field_types
=
dict
(
types
)
# Prior to PEP 526, only _field_types attribute was assigned.
# Now, both __annotations__ and _field_types are used to maintain compatibility.
nm_tpl
.
__annotations__
=
nm_tpl
.
_field_types
=
collections
.
OrderedDict
(
types
)
try
:
nm_tpl
.
__module__
=
sys
.
_getframe
(
2
).
f_globals
.
get
(
'__name__'
,
'__main__'
)
except
(
AttributeError
,
ValueError
):
...
...
@@ -1941,8 +1974,10 @@ class NamedTuple(metaclass=NamedTupleMeta):
Employee = collections.namedtuple('Employee', ['name', 'id'])
The resulting class has one extra attribute: _field_types,
giving a dict mapping field names to types. (The field names
The resulting class has extra __annotations__ and _field_types
attributes, giving an ordered dict mapping field names to types.
__annotations__ should be preferred, while _field_types
is kept to maintain pre PEP 526 compatibility. (The field names
are in the _fields attribute, which is part of the namedtuple
API.) Alternative equivalent keyword syntax is also accepted::
...
...
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