Skip to content

Commit aab2c59

Browse files
author
Guido van Rossum
committed
In B[<type>], insert B in front of __bases__, to make the __dict__ descriptor work.
Fixes CPython issue #25472.
1 parent c448a76 commit aab2c59

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

src/test_typing.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import pickle
12
import re
23
import sys
34
from unittest import TestCase, main
@@ -578,6 +579,35 @@ def test_repr(self):
578579
self.assertEqual(repr(MySimpleMapping),
579580
__name__ + '.' + 'MySimpleMapping[~XK, ~XV]')
580581

582+
def test_dict(self):
583+
T = TypeVar('T')
584+
class B(Generic[T]):
585+
pass
586+
b = B()
587+
b.foo = 42
588+
self.assertEqual(b.__dict__, {'foo': 42})
589+
class C(B[int]):
590+
pass
591+
c = C()
592+
c.bar = 'abc'
593+
self.assertEqual(c.__dict__, {'bar': 'abc'})
594+
595+
def test_pickle(self):
596+
T = TypeVar('T')
597+
class B(Generic[T]):
598+
pass
599+
global C # pickle wants to reference the class by name
600+
class C(B[int]):
601+
pass
602+
c = C()
603+
c.foo = 42
604+
c.bar = 'abc'
605+
z = pickle.dumps(c)
606+
x = pickle.loads(z)
607+
self.assertEqual(x.foo, 42)
608+
self.assertEqual(x.bar, 'abc')
609+
self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'})
610+
581611
def test_errors(self):
582612
with self.assertRaises(TypeError):
583613
B = SimpleMapping[XK, Any]

src/typing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ def __getitem__(self, params):
981981
"Cannot substitute %s for %s in %s" %
982982
(_type_repr(new), _type_repr(old), self))
983983

984-
return self.__class__(self.__name__, self.__bases__,
984+
return self.__class__(self.__name__, (self,) + self.__bases__,
985985
dict(self.__dict__),
986986
parameters=params,
987987
origin=self,

0 commit comments

Comments
 (0)