[Python-checkins] cpython (merge 3.3 -> default): merge 3.3

benjamin.peterson python-checkins at python.org
Wed Oct 31 05:08:15 CET 2012


http://hg.python.org/cpython/rev/2200aab16b56
changeset:   80079:2200aab16b56
parent:      80076:75fe7f5fda9a
parent:      80078:c21c894eefe1
user:        Benjamin Peterson <benjamin at python.org>
date:        Wed Oct 31 00:04:42 2012 -0400
summary:
  merge 3.3

files:
  Lib/test/test_descr.py |  16 ++++++++++++----
  Misc/NEWS              |   6 ++++++
  Objects/typeobject.c   |  11 ++++++-----
  3 files changed, 24 insertions(+), 9 deletions(-)


diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -4502,11 +4502,19 @@
         self.assertEqual(float.real.__qualname__, 'float.real')
         self.assertEqual(int.__add__.__qualname__, 'int.__add__')
 
+        class X:
+            pass
+        with self.assertRaises(TypeError):
+            del X.__qualname__
+
+        self.assertRaises(TypeError, type.__dict__['__qualname__'].__set__,
+                          str, 'Oink')
+
     def test_qualname_dict(self):
         ns = {'__qualname__': 'some.name'}
         tp = type('Foo', (), ns)
         self.assertEqual(tp.__qualname__, 'some.name')
-        self.assertEqual(tp.__dict__['__qualname__'], 'some.name')
+        self.assertNotIn('__qualname__', tp.__dict__)
         self.assertEqual(ns, {'__qualname__': 'some.name'})
 
         ns = {'__qualname__': 1}
@@ -4564,7 +4572,7 @@
         keys = list(it)
         keys.sort()
         self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
-                                '__qualname__', '__weakref__', 'meth'])
+                                '__weakref__', 'meth'])
 
     @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
                         'trace function introduces __local__')
@@ -4573,7 +4581,7 @@
         it = self.C.__dict__.values()
         self.assertNotIsInstance(it, list)
         values = list(it)
-        self.assertEqual(len(values), 6)
+        self.assertEqual(len(values), 5)
 
     @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
                         'trace function introduces __local__')
@@ -4584,7 +4592,7 @@
         keys = [item[0] for item in it]
         keys.sort()
         self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
-                                '__qualname__', '__weakref__', 'meth'])
+                                '__weakref__', 'meth'])
 
     def test_dict_type_with_metaclass(self):
         # Testing type of __dict__ when metaclass set...
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,9 +15,15 @@
   Py_TPFLAGS_TYPE_SUBCLASS ((1 << 31). PyType_GetFlags() result type is
   now unsigned too (unsigned long, instead of long).
 
+- Fix segfaults on setting __qualname__ on builtin types and attempting to
+  delete it on any type.
+
 - Issue #14625: Rewrite the UTF-32 decoder. It is now 3x to 4x faster. Patch
   written by Serhiy Storchaka.
 
+- Issue #16271: Fix strange bugs that resulted from __qualname__ appearing in a
+  class's __dict__ and on type.
+
 - Issue #16197: Update winreg docstrings and documentation to match code.
   Patch by Zachary Ware.
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -311,6 +311,8 @@
 {
     PyHeapTypeObject* et;
 
+    if (!check_set_special_type_attr(type, value, "__qualname__"))
+        return -1;
     if (!PyUnicode_Check(value)) {
         PyErr_Format(PyExc_TypeError,
                      "can only assign string to %s.__qualname__, not '%s'",
@@ -2250,11 +2252,10 @@
             goto error;
         }
     }
-    else {
-        qualname = et->ht_name;
-    }
-    Py_INCREF(qualname);
-    et->ht_qualname = qualname;
+    et->ht_qualname = qualname ? qualname : et->ht_name;
+    Py_INCREF(et->ht_qualname);
+    if (qualname != NULL && PyDict_DelItem(dict, PyId___qualname__.object) < 0)
+        goto error;
 
     /* Set tp_doc to a copy of dict['__doc__'], if the latter is there
        and is a string.  The __doc__ accessor will first look for tp_doc;

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list