diff -r ab25ce400abd Objects/dictobject.c --- a/Objects/dictobject.c Mon Feb 08 01:05:48 2016 +0200 +++ b/Objects/dictobject.c Mon Feb 08 12:25:42 2016 +0200 @@ -749,6 +749,36 @@ PyDict_GetItem(PyObject *op, PyObject *k 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 -r ab25ce400abd Python/import.c --- a/Python/import.c Mon Feb 08 01:05:48 2016 +0200 +++ b/Python/import.c Mon Feb 08 12:25:42 2016 +0200 @@ -626,31 +626,52 @@ PyObject * } +/* XXX: Will be moved to dictobject.h */ +PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *mp, PyObject *key); + /* Get the module object corresponding to a module name. First check the modules dictionary if there's one there, if not, create a new one and insert it in the modules dictionary. 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. */