mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
[3.10] bpo-44353: Expand NewType tests for complex __qualname__ (GH-27311) (GH-27326)
Make NewType pickleable by name.
(cherry picked from commit e89ef0ad2a)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
45caee2715
commit
05f5d8e48c
2 changed files with 48 additions and 15 deletions
|
|
@ -3673,28 +3673,35 @@ def foo(a: A) -> Optional[BaseException]:
|
||||||
|
|
||||||
|
|
||||||
class NewTypeTests(BaseTestCase):
|
class NewTypeTests(BaseTestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
global UserId
|
||||||
|
UserId = NewType('UserId', int)
|
||||||
|
cls.UserName = NewType(cls.__qualname__ + '.UserName', str)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
global UserId
|
||||||
|
del UserId
|
||||||
|
del cls.UserName
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.clear_caches()
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
UserId = NewType('UserId', int)
|
|
||||||
UserName = NewType('UserName', str)
|
|
||||||
self.assertIsInstance(UserId(5), int)
|
self.assertIsInstance(UserId(5), int)
|
||||||
self.assertIsInstance(UserName('Joe'), str)
|
self.assertIsInstance(self.UserName('Joe'), str)
|
||||||
self.assertEqual(UserId(5) + 1, 6)
|
self.assertEqual(UserId(5) + 1, 6)
|
||||||
|
|
||||||
def test_errors(self):
|
def test_errors(self):
|
||||||
UserId = NewType('UserId', int)
|
|
||||||
UserName = NewType('UserName', str)
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
issubclass(UserId, int)
|
issubclass(UserId, int)
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
class D(UserName):
|
class D(UserId):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_or(self):
|
def test_or(self):
|
||||||
UserId = NewType('UserId', int)
|
for cls in (int, self.UserName):
|
||||||
UserName = NewType('UserName', str)
|
|
||||||
|
|
||||||
for cls in (int, UserName):
|
|
||||||
with self.subTest(cls=cls):
|
with self.subTest(cls=cls):
|
||||||
self.assertEqual(UserId | cls, Union[UserId, cls])
|
self.assertEqual(UserId | cls, Union[UserId, cls])
|
||||||
self.assertEqual(cls | UserId, Union[cls, UserId])
|
self.assertEqual(cls | UserId, Union[cls, UserId])
|
||||||
|
|
@ -3703,16 +3710,37 @@ def test_or(self):
|
||||||
self.assertEqual(get_args(cls | UserId), (cls, UserId))
|
self.assertEqual(get_args(cls | UserId), (cls, UserId))
|
||||||
|
|
||||||
def test_special_attrs(self):
|
def test_special_attrs(self):
|
||||||
UserId = NewType('UserId', int)
|
|
||||||
|
|
||||||
self.assertEqual(UserId.__name__, 'UserId')
|
self.assertEqual(UserId.__name__, 'UserId')
|
||||||
self.assertEqual(UserId.__qualname__, 'UserId')
|
self.assertEqual(UserId.__qualname__, 'UserId')
|
||||||
self.assertEqual(UserId.__module__, __name__)
|
self.assertEqual(UserId.__module__, __name__)
|
||||||
|
self.assertEqual(UserId.__supertype__, int)
|
||||||
|
|
||||||
|
UserName = self.UserName
|
||||||
|
self.assertEqual(UserName.__name__, 'UserName')
|
||||||
|
self.assertEqual(UserName.__qualname__,
|
||||||
|
self.__class__.__qualname__ + '.UserName')
|
||||||
|
self.assertEqual(UserName.__module__, __name__)
|
||||||
|
self.assertEqual(UserName.__supertype__, str)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
UserId = NewType('UserId', int)
|
|
||||||
|
|
||||||
self.assertEqual(repr(UserId), f'{__name__}.UserId')
|
self.assertEqual(repr(UserId), f'{__name__}.UserId')
|
||||||
|
self.assertEqual(repr(self.UserName),
|
||||||
|
f'{__name__}.{self.__class__.__qualname__}.UserName')
|
||||||
|
|
||||||
|
def test_pickle(self):
|
||||||
|
UserAge = NewType('UserAge', float)
|
||||||
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
|
pickled = pickle.dumps(UserId, proto)
|
||||||
|
loaded = pickle.loads(pickled)
|
||||||
|
self.assertIs(loaded, UserId)
|
||||||
|
|
||||||
|
pickled = pickle.dumps(self.UserName, proto)
|
||||||
|
loaded = pickle.loads(pickled)
|
||||||
|
self.assertIs(loaded, self.UserName)
|
||||||
|
|
||||||
|
with self.assertRaises(pickle.PicklingError):
|
||||||
|
pickle.dumps(UserAge, proto)
|
||||||
|
|
||||||
|
|
||||||
class NamedTupleTests(BaseTestCase):
|
class NamedTupleTests(BaseTestCase):
|
||||||
class NestedEmployee(NamedTuple):
|
class NestedEmployee(NamedTuple):
|
||||||
|
|
|
||||||
|
|
@ -2375,8 +2375,10 @@ def name_by_id(user_id: UserId) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, tp):
|
def __init__(self, name, tp):
|
||||||
self.__name__ = name
|
|
||||||
self.__qualname__ = name
|
self.__qualname__ = name
|
||||||
|
if '.' in name:
|
||||||
|
name = name.rpartition('.')[-1]
|
||||||
|
self.__name__ = name
|
||||||
self.__module__ = _callee(default='typing')
|
self.__module__ = _callee(default='typing')
|
||||||
self.__supertype__ = tp
|
self.__supertype__ = tp
|
||||||
|
|
||||||
|
|
@ -2386,6 +2388,9 @@ def __repr__(self):
|
||||||
def __call__(self, x):
|
def __call__(self, x):
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return self.__qualname__
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
return Union[self, other]
|
return Union[self, other]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue