Skip to content

Commit 8afa7fa

Browse files
committed
don't shadow the __qualname__ descriptor with __qualname__ in the class's __dict__ (closes #16271)
1 parent e8ea97f commit 8afa7fa

3 files changed

Lines changed: 11 additions & 9 deletions

File tree

Lib/test/test_descr.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4506,7 +4506,7 @@ def test_qualname_dict(self):
45064506
ns = {'__qualname__': 'some.name'}
45074507
tp = type('Foo', (), ns)
45084508
self.assertEqual(tp.__qualname__, 'some.name')
4509-
self.assertEqual(tp.__dict__['__qualname__'], 'some.name')
4509+
self.assertNotIn('__qualname__', tp.__dict__)
45104510
self.assertEqual(ns, {'__qualname__': 'some.name'})
45114511

45124512
ns = {'__qualname__': 1}
@@ -4564,7 +4564,7 @@ def test_iter_keys(self):
45644564
keys = list(it)
45654565
keys.sort()
45664566
self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
4567-
'__qualname__', '__weakref__', 'meth'])
4567+
'__weakref__', 'meth'])
45684568

45694569
@unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
45704570
'trace function introduces __local__')
@@ -4573,7 +4573,7 @@ def test_iter_values(self):
45734573
it = self.C.__dict__.values()
45744574
self.assertNotIsInstance(it, list)
45754575
values = list(it)
4576-
self.assertEqual(len(values), 6)
4576+
self.assertEqual(len(values), 5)
45774577

45784578
@unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
45794579
'trace function introduces __local__')
@@ -4584,7 +4584,7 @@ def test_iter_items(self):
45844584
keys = [item[0] for item in it]
45854585
keys.sort()
45864586
self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
4587-
'__qualname__', '__weakref__', 'meth'])
4587+
'__weakref__', 'meth'])
45884588

45894589
def test_dict_type_with_metaclass(self):
45904590
# Testing type of __dict__ when metaclass set...

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 3.3.1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #16271: Fix strange bugs that resulted from __qualname__ appearing in a
16+
class's __dict__ and on type.
17+
1518
- Issue #16197: Update winreg docstrings and documentation to match code.
1619
Patch by Zachary Ware.
1720

Objects/typeobject.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,11 +2250,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
22502250
goto error;
22512251
}
22522252
}
2253-
else {
2254-
qualname = et->ht_name;
2255-
}
2256-
Py_INCREF(qualname);
2257-
et->ht_qualname = qualname;
2253+
et->ht_qualname = qualname ? qualname : et->ht_name;
2254+
Py_INCREF(et->ht_qualname);
2255+
if (qualname != NULL && PyDict_DelItem(dict, PyId___qualname__.object) < 0)
2256+
goto error;
22582257

22592258
/* Set tp_doc to a copy of dict['__doc__'], if the latter is there
22602259
and is a string. The __doc__ accessor will first look for tp_doc;

0 commit comments

Comments
 (0)