[Python-checkins] cpython (2.7): Issue #25698: Importing module if the stack is too deep no longer replaces
serhiy.storchaka
python-checkins at python.org
Wed Feb 10 03:33:36 EST 2016
https://hg.python.org/cpython/rev/81dba6e392c3
changeset: 100214:81dba6e392c3
branch: 2.7
user: Serhiy Storchaka <storchaka at gmail.com>
date: Wed Feb 10 10:28:06 2016 +0200
summary:
Issue #25698: Importing module if the stack is too deep no longer replaces
imported module with the empty one.
files:
Include/dictobject.h | 1 +
Misc/NEWS | 3 ++
Objects/dictobject.c | 30 ++++++++++++++++++++
Python/import.c | 48 ++++++++++++++++++++++----------
4 files changed, 67 insertions(+), 15 deletions(-)
diff --git a/Include/dictobject.h b/Include/dictobject.h
--- a/Include/dictobject.h
+++ b/Include/dictobject.h
@@ -108,6 +108,7 @@
PyAPI_FUNC(PyObject *) PyDict_New(void);
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
+PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *mp, PyObject *key);
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,9 @@
Library
-------
+- Issue #25698: Importing module if the stack is too deep no longer replaces
+ imported module with the empty one.
+
- Issue #12923: Reset FancyURLopener's redirect counter even if there is an
exception. Based on patches by Brian Brazil and Daniel Rocco.
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -749,6 +749,36 @@
return ep->me_value;
}
+/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
+ This returns NULL *with* an exception set if an exception occurred.
+ It returns NULL *without* an exception set if the key wasn't present.
+*/
+PyObject *
+_PyDict_GetItemWithError(PyObject *op, PyObject *key)
+{
+ long hash;
+ PyDictObject *mp = (PyDictObject *)op;
+ PyDictEntry *ep;
+ if (!PyDict_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1)
+ {
+ hash = PyObject_Hash(key);
+ if (hash == -1) {
+ return NULL;
+ }
+ }
+
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL) {
+ return NULL;
+ }
+ return ep->me_value;
+}
+
static int
dict_set_item_by_hash_or_entry(register PyObject *op, PyObject *key,
long hash, PyDictEntry *ep, PyObject *value)
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -632,25 +632,43 @@
Because the former action is most common, THIS DOES NOT RETURN A
'NEW' REFERENCE! */
+static PyObject *
+_PyImport_AddModuleObject(PyObject *name)
+{
+ PyObject *modules = PyImport_GetModuleDict();
+ PyObject *m;
+
+ if ((m = _PyDict_GetItemWithError(modules, name)) != NULL &&
+ PyModule_Check(m)) {
+ return m;
+ }
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ m = PyModule_New(PyString_AS_STRING(name));
+ if (m == NULL) {
+ return NULL;
+ }
+ if (PyDict_SetItem(modules, name, m) != 0) {
+ Py_DECREF(m);
+ return NULL;
+ }
+ assert(Py_REFCNT(m) > 1);
+ Py_DECREF(m); /* Yes, it still exists, in modules! */
+
+ return m;
+}
+
PyObject *
PyImport_AddModule(const char *name)
{
- PyObject *modules = PyImport_GetModuleDict();
- PyObject *m;
-
- if ((m = PyDict_GetItemString(modules, name)) != NULL &&
- PyModule_Check(m))
- return m;
- m = PyModule_New(name);
- if (m == NULL)
+ PyObject *nameobj, *module;
+ nameobj = PyString_FromString(name);
+ if (nameobj == NULL)
return NULL;
- if (PyDict_SetItemString(modules, name, m) != 0) {
- Py_DECREF(m);
- return NULL;
- }
- Py_DECREF(m); /* Yes, it still exists, in modules! */
-
- return m;
+ module = _PyImport_AddModuleObject(nameobj);
+ Py_DECREF(nameobj);
+ return module;
}
/* Remove name from sys.modules, if it's there. */
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list