[Python-checkins] cpython: Fix uninitialized variable after #22676.

antoine.pitrou python-checkins at python.org
Tue Dec 2 00:20:28 CET 2014


https://hg.python.org/cpython/rev/3e3bec66409c
changeset: 93696:3e3bec66409c
user: Antoine Pitrou <solipsis at pitrou.net>
date: Tue Dec 02 00:20:03 2014 +0100
summary:
 Fix uninitialized variable after #22676.
files:
 Lib/test/pickletester.py | 21 +++++++++++++++++++++
 Modules/_pickle.c | 24 +++++++++++++++++-------
 2 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -1636,6 +1636,27 @@
 unpickled = self.loads(self.dumps(method, proto))
 self.assertEqual(method(*args), unpickled(*args))
 
+ def test_local_lookup_error(self):
+ # Test that whichmodule() errors out cleanly when looking up
+ # an assumed globally-reachable object fails.
+ def f():
+ pass
+ # Since the function is local, lookup will fail
+ for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
+ with self.assertRaises((AttributeError, pickle.PicklingError)):
+ pickletools.dis(self.dumps(f, proto))
+ # Same without a __module__ attribute (exercises a different path
+ # in _pickle.c).
+ del f.__module__
+ for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
+ with self.assertRaises((AttributeError, pickle.PicklingError)):
+ pickletools.dis(self.dumps(f, proto))
+ # Yet a different path.
+ f.__name__ = f.__qualname__
+ for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
+ with self.assertRaises((AttributeError, pickle.PicklingError)):
+ pickletools.dis(self.dumps(f, proto))
+
 
 class BigmemPickleTests(unittest.TestCase):
 
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -1547,10 +1547,16 @@
 n = PyList_GET_SIZE(dotted_path);
 assert(n >= 1);
 if (!allow_qualname && n > 1) {
- PyErr_Format(PyExc_AttributeError,
- "Can't get qualified attribute %R on %R;"
- "use protocols >= 4 to enable support",
- name, obj);
+ if (obj == NULL)
+ PyErr_Format(PyExc_AttributeError,
+ "Can't pickle qualified object %R; "
+ "use protocols >= 4 to enable support",
+ name);
+ else
+ PyErr_Format(PyExc_AttributeError,
+ "Can't pickle qualified attribute %R on %R; "
+ "use protocols >= 4 to enable support",
+ name, obj);
 Py_DECREF(dotted_path);
 return NULL;
 }
@@ -1562,8 +1568,12 @@
 assert(PyBool_Check(result));
 Py_DECREF(result);
 if (is_equal) {
- PyErr_Format(PyExc_AttributeError,
- "Can't get local attribute %R on %R", name, obj);
+ if (obj == NULL)
+ PyErr_Format(PyExc_AttributeError,
+ "Can't pickle local object %R", name);
+ else
+ PyErr_Format(PyExc_AttributeError,
+ "Can't pickle local attribute %R on %R", name, obj);
 Py_DECREF(dotted_path);
 return NULL;
 }
@@ -1653,7 +1663,7 @@
 return NULL;
 }
 
- dotted_path = get_dotted_path(module, global_name, allow_qualname);
+ dotted_path = get_dotted_path(NULL, global_name, allow_qualname);
 if (dotted_path == NULL)
 return NULL;
 
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /