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
94cc5633
Commit
94cc5633
authored
Oct 03, 2016
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More updates from upstream typing.py
parent
464bb8b3
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
108 additions
and
64 deletions
+108
-64
Lib/test/test_typing.py
Lib/test/test_typing.py
+38
-29
Lib/typing.py
Lib/typing.py
+70
-35
No files found.
Lib/test/test_typing.py
View file @
94cc5633
...
...
@@ -202,10 +202,13 @@ class UnionTests(BaseTestCase):
def
test_union_any
(
self
):
u
=
Union
[
Any
]
self
.
assertEqual
(
u
,
Any
)
u
=
Union
[
int
,
Any
]
self
.
assertEqual
(
u
,
Any
)
u
=
Union
[
Any
,
int
]
self
.
assertEqual
(
u
,
Any
)
u1
=
Union
[
int
,
Any
]
u2
=
Union
[
Any
,
int
]
u3
=
Union
[
Any
,
object
]
self
.
assertEqual
(
u1
,
u2
)
self
.
assertNotEqual
(
u1
,
Any
)
self
.
assertNotEqual
(
u2
,
Any
)
self
.
assertNotEqual
(
u3
,
Any
)
def
test_union_object
(
self
):
u
=
Union
[
object
]
...
...
@@ -215,12 +218,6 @@ class UnionTests(BaseTestCase):
u
=
Union
[
object
,
int
]
self
.
assertEqual
(
u
,
object
)
def
test_union_any_object
(
self
):
u
=
Union
[
object
,
Any
]
self
.
assertEqual
(
u
,
Any
)
u
=
Union
[
Any
,
object
]
self
.
assertEqual
(
u
,
Any
)
def
test_unordered
(
self
):
u1
=
Union
[
int
,
float
]
u2
=
Union
[
float
,
int
]
...
...
@@ -600,8 +597,8 @@ class GenericTests(BaseTestCase):
self
.
assertNotIsInstance
({},
MyMapping
)
self
.
assertNotIsSubclass
(
dict
,
MyMapping
)
def
test_
multiple_
abc_bases
(
self
):
class
MM
1
(
MutableMapping
[
str
,
str
],
collections_abc
.
MutableMapping
):
def
test_abc_bases
(
self
):
class
MM
(
MutableMapping
[
str
,
str
]
):
def
__getitem__
(
self
,
k
):
return
None
def
__setitem__
(
self
,
k
,
v
):
...
...
@@ -612,24 +609,20 @@ class GenericTests(BaseTestCase):
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
):
# this should just work
MM
().
update
()
self
.
assertIsInstance
(
MM
(),
collections_abc
.
MutableMapping
)
self
.
assertIsInstance
(
MM
(),
MutableMapping
)
self
.
assertNotIsInstance
(
MM
(),
List
)
self
.
assertNotIsInstance
({},
MM
)
def
test_multiple_bases
(
self
):
class
MM1
(
MutableMapping
[
str
,
str
],
collections_abc
.
MutableMapping
):
pass
with
self
.
assertRaises
(
TypeError
):
# consistent MRO not possible
class
MM2
(
collections_abc
.
MutableMapping
,
MutableMapping
[
str
,
str
]):
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
...
...
@@ -1380,12 +1373,28 @@ class CollectionsAbcTests(BaseTestCase):
MMA
()
class
MMC
(
MMA
):
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
self
.
assertEqual
(
len
(
MMC
()),
0
)
class
MMB
(
typing
.
MutableMapping
[
KT
,
VT
]):
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
...
...
Lib/typing.py
View file @
94cc5633
...
...
@@ -143,7 +143,6 @@ class _TypingBase(metaclass=TypingMeta, _root=True):
__slots__
=
()
def
__init__
(
self
,
*
args
,
**
kwds
):
pass
...
...
@@ -158,7 +157,7 @@ class _TypingBase(metaclass=TypingMeta, _root=True):
isinstance
(
args
[
1
],
tuple
)):
# Close enough.
raise
TypeError
(
"Cannot subclass %r"
%
cls
)
return
object
.
__new__
(
cls
)
return
super
()
.
__new__
(
cls
)
# Things that are not classes also need these.
def
_eval_type
(
self
,
globalns
,
localns
):
...
...
@@ -177,7 +176,11 @@ class _TypingBase(metaclass=TypingMeta, _root=True):
class
_FinalTypingBase
(
_TypingBase
,
_root
=
True
):
"""Mix-in class to prevent instantiation."""
"""Mix-in class to prevent instantiation.
Prevents instantiation unless _root=True is given in class call.
It is used to create pseudo-singleton instances Any, Union, Tuple, etc.
"""
__slots__
=
()
...
...
@@ -273,7 +276,7 @@ class _TypeAlias(_TypingBase, _root=True):
assert
isinstance
(
name
,
str
),
repr
(
name
)
assert
isinstance
(
impl_type
,
type
),
repr
(
impl_type
)
assert
not
isinstance
(
impl_type
,
TypingMeta
),
repr
(
impl_type
)
assert
isinstance
(
type_var
,
(
type
,
_TypingBase
))
assert
isinstance
(
type_var
,
(
type
,
_TypingBase
))
,
repr
(
type_var
)
self
.
name
=
name
self
.
type_var
=
type_var
self
.
impl_type
=
impl_type
...
...
@@ -375,9 +378,13 @@ def _type_repr(obj):
class
_Any
(
_FinalTypingBase
,
_root
=
True
):
"""Special type indicating an unconstrained type.
- Any object is an instance of Any.
- Any class is a subclass of Any.
- As a special case, Any and object are subclasses of each other.
- Any is compatible with every type.
- Any assumed to have all methods.
- All values assumed to be instances of Any.
Note that all the above statements are true from the point of view of
static type checkers. At runtime, Any should not be used with instance
or class checks.
"""
__slots__
=
()
...
...
@@ -502,7 +509,7 @@ def _tp_cache(func):
try
:
return
cached
(
*
args
,
**
kwds
)
except
TypeError
:
pass
#
Do not duplicate real errors
.
pass
#
All real errors (not unhashable args) are raised below
.
return
func
(
*
args
,
**
kwds
)
return
inner
...
...
@@ -542,16 +549,10 @@ class _Union(_FinalTypingBase, _root=True):
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?).
...
...
@@ -589,14 +590,11 @@ class _Union(_FinalTypingBase, _root=True):
assert
not
all_params
,
all_params
# Weed out subclasses.
# E.g. Union[int, Employee, Manager] == Union[int, Employee].
# If Any or object is present it will be the sole survivor.
# If both Any and object are present, Any wins.
# Never discard type variables, except against Any.
# If object is present it will be sole survivor among proper classes.
# Never discard type variables.
# (In particular, Union[str, AnyStr] != AnyStr.)
all_params
=
set
(
params
)
for
t1
in
params
:
if
t1
is
Any
:
return
Any
if
not
isinstance
(
t1
,
type
):
continue
if
any
(
isinstance
(
t2
,
type
)
and
issubclass
(
t1
,
t2
)
...
...
@@ -662,7 +660,7 @@ Union = _Union(_root=True)
class
_Optional
(
_FinalTypingBase
,
_root
=
True
):
"""Optional type.
Optional[X] is equivalent to Union[X,
type(None)
].
Optional[X] is equivalent to Union[X,
None
].
"""
__slots__
=
()
...
...
@@ -894,11 +892,55 @@ def _next_in_mro(cls):
return
next_in_mro
def
_valid_for_check
(
cls
):
if
cls
is
Generic
:
raise
TypeError
(
"Class %r cannot be used with class "
"or instance checks"
%
cls
)
if
(
cls
.
__origin__
is
not
None
and
sys
.
_getframe
(
3
).
f_globals
[
'__name__'
]
not
in
[
'abc'
,
'functools'
]):
raise
TypeError
(
"Parameterized generics cannot be used with class "
"or instance checks"
)
def
_make_subclasshook
(
cls
):
"""Construct a __subclasshook__ callable that incorporates
the associated __extra__ class in subclass checks performed
against cls.
"""
if
isinstance
(
cls
.
__extra__
,
abc
.
ABCMeta
):
# The logic mirrors that of ABCMeta.__subclasscheck__.
# Registered classes need not be checked here because
# cls and its extra share the same _abc_registry.
def
__extrahook__
(
subclass
):
_valid_for_check
(
cls
)
res
=
cls
.
__extra__
.
__subclasshook__
(
subclass
)
if
res
is
not
NotImplemented
:
return
res
if
cls
.
__extra__
in
subclass
.
__mro__
:
return
True
for
scls
in
cls
.
__extra__
.
__subclasses__
():
if
isinstance
(
scls
,
GenericMeta
):
continue
if
issubclass
(
subclass
,
scls
):
return
True
return
NotImplemented
else
:
# For non-ABC extras we'll just call issubclass().
def
__extrahook__
(
subclass
):
_valid_for_check
(
cls
)
if
cls
.
__extra__
and
issubclass
(
subclass
,
cls
.
__extra__
):
return
True
return
NotImplemented
return
__extrahook__
class
GenericMeta
(
TypingMeta
,
abc
.
ABCMeta
):
"""Metaclass for generic types."""
def
__new__
(
cls
,
name
,
bases
,
namespace
,
tvars
=
None
,
args
=
None
,
origin
=
None
,
extra
=
None
):
if
extra
is
not
None
and
type
(
extra
)
is
abc
.
ABCMeta
and
extra
not
in
bases
:
bases
=
(
extra
,)
+
bases
self
=
super
().
__new__
(
cls
,
name
,
bases
,
namespace
,
_root
=
True
)
if
tvars
is
not
None
:
...
...
@@ -947,6 +989,13 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
self
.
__extra__
=
extra
# Speed hack (https://github.com/python/typing/issues/196).
self
.
__next_in_mro__
=
_next_in_mro
(
self
)
# This allows unparameterized generic collections to be used
# with issubclass() and isinstance() in the same way as their
# collections.abc counterparts (e.g., isinstance([], Iterable)).
self
.
__subclasshook__
=
_make_subclasshook
(
self
)
if
isinstance
(
extra
,
abc
.
ABCMeta
):
self
.
_abc_registry
=
extra
.
_abc_registry
return
self
def
_get_type_vars
(
self
,
tvars
):
...
...
@@ -1032,21 +1081,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
# latter, we must extend __instancecheck__ too. For simplicity
# we just skip the cache check -- instance checks for generic
# classes are supposed to be rare anyways.
return
self
.
__subclasscheck__
(
instance
.
__class__
)
def
__subclasscheck__
(
self
,
cls
):
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
not
None
:
return
issubclass
(
cls
,
self
.
__extra__
)
return
False
return
issubclass
(
instance
.
__class__
,
self
)
# Prevent checks for Generic to crash when defining Generic.
...
...
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