Skip to content

Commit e89ef0a

Browse files
bpo-44353: Expand NewType tests for complex __qualname__. (#27311)
Make NewType pickleable by name.
1 parent 4512848 commit e89ef0a

File tree

2 files changed

+47
-18
lines changed

2 files changed

+47
-18
lines changed

Lib/test/test_typing.py

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3696,34 +3696,37 @@ def cleanup(self):
36963696
for f in self.module._cleanups:
36973697
f()
36983698

3699-
def setUp(self):
3700-
sys.modules['typing'] = self.module
3699+
@classmethod
3700+
def setUpClass(cls):
3701+
sys.modules['typing'] = cls.module
3702+
global UserId
3703+
UserId = cls.module.NewType('UserId', int)
3704+
cls.UserName = cls.module.NewType(cls.__qualname__ + '.UserName', str)
3705+
3706+
@classmethod
3707+
def tearDownClass(cls):
3708+
global UserId
3709+
del UserId
3710+
del cls.UserName
3711+
sys.modules['typing'] = typing
37013712

37023713
def tearDown(self):
37033714
self.cleanup()
3704-
sys.modules['typing'] = typing
37053715

37063716
def test_basic(self):
3707-
UserId = self.module.NewType('UserId', int)
3708-
UserName = self.module.NewType('UserName', str)
37093717
self.assertIsInstance(UserId(5), int)
3710-
self.assertIsInstance(UserName('Joe'), str)
3718+
self.assertIsInstance(self.UserName('Joe'), str)
37113719
self.assertEqual(UserId(5) + 1, 6)
37123720

37133721
def test_errors(self):
3714-
UserId = self.module.NewType('UserId', int)
3715-
UserName = self.module.NewType('UserName', str)
37163722
with self.assertRaises(TypeError):
37173723
issubclass(UserId, int)
37183724
with self.assertRaises(TypeError):
3719-
class D(UserName):
3725+
class D(UserId):
37203726
pass
37213727

37223728
def test_or(self):
3723-
UserId = self.module.NewType('UserId', int)
3724-
UserName = self.module.NewType('UserName', str)
3725-
3726-
for cls in (int, UserName):
3729+
for cls in (int, self.UserName):
37273730
with self.subTest(cls=cls):
37283731
self.assertEqual(UserId | cls, self.module.Union[UserId, cls])
37293732
self.assertEqual(cls | UserId, self.module.Union[cls, UserId])
@@ -3732,16 +3735,37 @@ def test_or(self):
37323735
self.assertEqual(self.module.get_args(cls | UserId), (cls, UserId))
37333736

37343737
def test_special_attrs(self):
3735-
UserId = self.module.NewType('UserId', int)
3736-
37373738
self.assertEqual(UserId.__name__, 'UserId')
37383739
self.assertEqual(UserId.__qualname__, 'UserId')
37393740
self.assertEqual(UserId.__module__, __name__)
3741+
self.assertEqual(UserId.__supertype__, int)
37403742

3741-
def test_repr(self):
3742-
UserId = self.module.NewType('UserId', int)
3743+
UserName = self.UserName
3744+
self.assertEqual(UserName.__name__, 'UserName')
3745+
self.assertEqual(UserName.__qualname__,
3746+
self.__class__.__qualname__ + '.UserName')
3747+
self.assertEqual(UserName.__module__, __name__)
3748+
self.assertEqual(UserName.__supertype__, str)
37433749

3750+
def test_repr(self):
37443751
self.assertEqual(repr(UserId), f'{__name__}.UserId')
3752+
self.assertEqual(repr(self.UserName),
3753+
f'{__name__}.{self.__class__.__qualname__}.UserName')
3754+
3755+
def test_pickle(self):
3756+
UserAge = self.module.NewType('UserAge', float)
3757+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
3758+
pickled = pickle.dumps(UserId, proto)
3759+
loaded = pickle.loads(pickled)
3760+
self.assertIs(loaded, UserId)
3761+
3762+
pickled = pickle.dumps(self.UserName, proto)
3763+
loaded = pickle.loads(pickled)
3764+
self.assertIs(loaded, self.UserName)
3765+
3766+
with self.assertRaises(pickle.PicklingError):
3767+
pickle.dumps(UserAge, proto)
3768+
37453769

37463770
class NewTypePythonTests(NewTypeTests, BaseTestCase):
37473771
module = py_typing

Lib/typing.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2385,14 +2385,19 @@ def name_by_id(user_id: UserId) -> str:
23852385
__call__ = _idfunc
23862386

23872387
def __init__(self, name, tp):
2388-
self.__name__ = name
23892388
self.__qualname__ = name
2389+
if '.' in name:
2390+
name = name.rpartition('.')[-1]
2391+
self.__name__ = name
23902392
self.__module__ = _callee(default='typing')
23912393
self.__supertype__ = tp
23922394

23932395
def __repr__(self):
23942396
return f'{self.__module__}.{self.__qualname__}'
23952397

2398+
def __reduce__(self):
2399+
return self.__qualname__
2400+
23962401
def __or__(self, other):
23972402
return Union[self, other]
23982403

0 commit comments

Comments
 (0)