Issue #25472: In B[<type>], insert B in front of __bases__, to make the __dict__ descriptor work. (Merge 3.5->3.6)

This commit is contained in:
Guido van Rossum 2015-11-18 21:13:42 -08:00
commit 5497ac4758
2 changed files with 31 additions and 1 deletions

View File

@ -1,4 +1,5 @@
from collections import namedtuple
import pickle
import re
import sys
from unittest import TestCase, main
@ -583,6 +584,35 @@ class GenericTests(TestCase):
self.assertEqual(repr(MySimpleMapping),
__name__ + '.' + 'MySimpleMapping[~XK, ~XV]')
def test_dict(self):
T = TypeVar('T')
class B(Generic[T]):
pass
b = B()
b.foo = 42
self.assertEqual(b.__dict__, {'foo': 42})
class C(B[int]):
pass
c = C()
c.bar = 'abc'
self.assertEqual(c.__dict__, {'bar': 'abc'})
def test_pickle(self):
T = TypeVar('T')
class B(Generic[T]):
pass
global C # pickle wants to reference the class by name
class C(B[int]):
pass
c = C()
c.foo = 42
c.bar = 'abc'
z = pickle.dumps(c)
x = pickle.loads(z)
self.assertEqual(x.foo, 42)
self.assertEqual(x.bar, 'abc')
self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'})
def test_errors(self):
with self.assertRaises(TypeError):
B = SimpleMapping[XK, Any]

View File

@ -981,7 +981,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
"Cannot substitute %s for %s in %s" %
(_type_repr(new), _type_repr(old), self))
return self.__class__(self.__name__, self.__bases__,
return self.__class__(self.__name__, (self,) + self.__bases__,
dict(self.__dict__),
parameters=params,
origin=self,