[Python-checkins] cpython (3.4): look up __getnewargs__ and __getnewargs_ex__ on the object type (#16251)

larry.hastings python-checkins at python.org
Mon Mar 17 07:31:44 CET 2014


http://hg.python.org/cpython/rev/2514a577c7cb
changeset:   89713:2514a577c7cb
branch:      3.4
user:        Benjamin Peterson <benjamin at python.org>
date:        Sun Feb 16 13:49:16 2014 -0500
summary:
  look up __getnewargs__ and __getnewargs_ex__ on the object type (#16251)

files:
  Lib/test/test_descr.py |  14 ++++++++++++++
  Misc/NEWS              |   3 +++
  Objects/typeobject.c   |  18 ++++++------------
  3 files changed, 23 insertions(+), 12 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
@@ -4701,6 +4701,20 @@
         for proto in protocols:
             self._check_reduce(proto, obj, listitems=list(obj))
 
+    def test_special_method_lookup(self):
+        protocols = range(pickle.HIGHEST_PROTOCOL + 1)
+        class Picky:
+            def __getstate__(self):
+                return {}
+
+            def __getattr__(self, attr):
+                if attr in ("__getnewargs__", "__getnewargs_ex__"):
+                    raise AssertionError(attr)
+                return None
+        for protocol in protocols:
+            state = {} if protocol >= 2 else None
+            self._check_reduce(protocol, Picky(), state=state)
+
     def _assert_is_copy(self, obj, objcopy, msg=None):
         """Utility method to verify if two objects are copies of each others.
         """
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #20261: In pickle, lookup __getnewargs__ and __getnewargs_ex__ on the
+  type of the object.
+
 - Issue #20619: Give the AST nodes of keyword-only arguments a column and line
   number.
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3719,7 +3719,7 @@
 
     /* We first attempt to fetch the arguments for __new__ by calling
        __getnewargs_ex__ on the object. */
-    getnewargs_ex = _PyObject_GetAttrId(obj, &PyId___getnewargs_ex__);
+    getnewargs_ex = _PyObject_LookupSpecial(obj, &PyId___getnewargs_ex__);
     if (getnewargs_ex != NULL) {
         PyObject *newargs = PyObject_CallObject(getnewargs_ex, NULL);
         Py_DECREF(getnewargs_ex);
@@ -3766,16 +3766,13 @@
             return -1;
         }
         return 0;
-    } else {
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
-            return -1;
-        }
-        PyErr_Clear();
+    } else if (PyErr_Occurred()) {
+        return -1;
     }
 
     /* The object does not have __getnewargs_ex__ so we fallback on using
        __getnewargs__ instead. */
-    getnewargs = _PyObject_GetAttrId(obj, &PyId___getnewargs__);
+    getnewargs = _PyObject_LookupSpecial(obj, &PyId___getnewargs__);
     if (getnewargs != NULL) {
         *args = PyObject_CallObject(getnewargs, NULL);
         Py_DECREF(getnewargs);
@@ -3791,11 +3788,8 @@
         }
         *kwargs = NULL;
         return 0;
-    } else {
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
-            return -1;
-        }
-        PyErr_Clear();
+    } else if (PyErr_Occurred()) {
+        return -1;
     }
 
     /* The object does not have __getnewargs_ex__ and __getnewargs__. This may

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


More information about the Python-checkins mailing list