diff -r 784fea019cab Lib/test/test_descr.py --- a/Lib/test/test_descr.py Wed Nov 09 18:57:00 2016 -0500 +++ b/Lib/test/test_descr.py Thu Nov 10 21:47:39 2016 +0800 @@ -1284,7 +1284,7 @@ del X().a def test_slots_special(self): - # Testing __dict__ and __weakref__ in __slots__... + # Testing special slots like __dict__ and __weakref__ in __slots__ class D(object): __slots__ = ["__dict__"] a = D() @@ -1305,6 +1305,27 @@ else: self.fail("shouldn't be allowed to set a.foo") + class Q: + __slots__ = ["__qualname__"] + a = Q() + self.assertNotHasAttr(a, "__qualname__") + a.__qualname__ = "a" + self.assertEqual(a.__qualname__, "a") + self.assertEqual(Q.__qualname__, D.__qualname__[:-1] + "Q") + + class L1: + def __init__(self): + self.b = 42 + class L2(L1): + __slots__ = ["__classcell__"] + def __init__(self): + super().__init__() + a = L2() + self.assertEqual(a.b, 42) + self.assertNotHasAttr(a, "__classcell__") + a.__classcell__ = 42 + self.assertEqual(a.__classcell__, 42) + class C1(W, D): __slots__ = [] a = C1() diff -r 784fea019cab Objects/typeobject.c --- a/Objects/typeobject.c Wed Nov 09 18:57:00 2016 -0500 +++ b/Objects/typeobject.c Thu Nov 10 21:47:39 2016 +0800 @@ -2444,7 +2444,12 @@ goto error; } PyList_SET_ITEM(newslots, j, tmp); - if (PyDict_GetItem(dict, tmp)) { + /* CPython inserts __qualname__ and __classcell__ (when needed) + into the namespace when creating a class. They will be deleted + below so won't act as a class variable.*/ + if (PyDict_GetItem(dict, tmp) && + _PyUnicode_CompareWithId(tmp, &PyId___qualname__) != 0 && + _PyUnicode_CompareWithId(tmp, &PyId___classcell__) != 0) { PyErr_Format(PyExc_ValueError, "%R in __slots__ conflicts with class variable", tmp);