Merge further typing.py changes from upstream. (merge 3.5->3.6)

This commit is contained in:
Guido van Rossum 2016-10-08 20:27:55 -07:00
commit 518599b24c
2 changed files with 83 additions and 1 deletions

View File

@ -20,6 +20,7 @@ from typing import NewType
from typing import NamedTuple from typing import NamedTuple
from typing import IO, TextIO, BinaryIO from typing import IO, TextIO, BinaryIO
from typing import Pattern, Match from typing import Pattern, Match
import abc
import typing import typing
try: try:
import collections.abc as collections_abc import collections.abc as collections_abc
@ -1385,6 +1386,8 @@ class CollectionsAbcTests(BaseTestCase):
return 0 return 0
self.assertEqual(len(MMC()), 0) self.assertEqual(len(MMC()), 0)
assert callable(MMC.update)
self.assertIsInstance(MMC(), typing.Mapping)
class MMB(typing.MutableMapping[KT, VT]): class MMB(typing.MutableMapping[KT, VT]):
def __getitem__(self, k): def __getitem__(self, k):
@ -1409,6 +1412,82 @@ class CollectionsAbcTests(BaseTestCase):
self.assertIsSubclass(MMB, typing.Mapping) self.assertIsSubclass(MMB, typing.Mapping)
self.assertIsSubclass(MMC, typing.Mapping) self.assertIsSubclass(MMC, typing.Mapping)
self.assertIsInstance(MMB[KT, VT](), typing.Mapping)
self.assertIsInstance(MMB[KT, VT](), collections.Mapping)
self.assertIsSubclass(MMA, collections.Mapping)
self.assertIsSubclass(MMB, collections.Mapping)
self.assertIsSubclass(MMC, collections.Mapping)
self.assertIsSubclass(MMB[str, str], typing.Mapping)
self.assertIsSubclass(MMC, MMA)
class I(typing.Iterable): ...
self.assertNotIsSubclass(list, I)
class G(typing.Generator[int, int, int]): ...
def g(): yield 0
self.assertIsSubclass(G, typing.Generator)
self.assertIsSubclass(G, typing.Iterable)
if hasattr(collections, 'Generator'):
self.assertIsSubclass(G, collections.Generator)
self.assertIsSubclass(G, collections.Iterable)
self.assertNotIsSubclass(type(g), G)
def test_subclassing_subclasshook(self):
class Base(typing.Iterable):
@classmethod
def __subclasshook__(cls, other):
if other.__name__ == 'Foo':
return True
else:
return False
class C(Base): ...
class Foo: ...
class Bar: ...
self.assertIsSubclass(Foo, Base)
self.assertIsSubclass(Foo, C)
self.assertNotIsSubclass(Bar, C)
def test_subclassing_register(self):
class A(typing.Container): ...
class B(A): ...
class C: ...
A.register(C)
self.assertIsSubclass(C, A)
self.assertNotIsSubclass(C, B)
class D: ...
B.register(D)
self.assertIsSubclass(D, A)
self.assertIsSubclass(D, B)
class M(): ...
collections.MutableMapping.register(M)
self.assertIsSubclass(M, typing.Mapping)
def test_collections_as_base(self):
class M(collections.Mapping): ...
self.assertIsSubclass(M, typing.Mapping)
self.assertIsSubclass(M, typing.Iterable)
class S(collections.MutableSequence): ...
self.assertIsSubclass(S, typing.MutableSequence)
self.assertIsSubclass(S, typing.Iterable)
class I(collections.Iterable): ...
self.assertIsSubclass(I, typing.Iterable)
class A(collections.Mapping, metaclass=abc.ABCMeta): ...
class B: ...
A.register(B)
self.assertIsSubclass(B, typing.Mapping)
class OtherABCTests(BaseTestCase): class OtherABCTests(BaseTestCase):

View File

@ -993,7 +993,10 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
# This allows unparameterized generic collections to be used # This allows unparameterized generic collections to be used
# with issubclass() and isinstance() in the same way as their # with issubclass() and isinstance() in the same way as their
# collections.abc counterparts (e.g., isinstance([], Iterable)). # collections.abc counterparts (e.g., isinstance([], Iterable)).
self.__subclasshook__ = _make_subclasshook(self) if ('__subclasshook__' not in namespace and extra # allow overriding
or hasattr(self.__subclasshook__, '__name__') and
self.__subclasshook__.__name__ == '__extrahook__'):
self.__subclasshook__ = _make_subclasshook(self)
if isinstance(extra, abc.ABCMeta): if isinstance(extra, abc.ABCMeta):
self._abc_registry = extra._abc_registry self._abc_registry = extra._abc_registry
return self return self