Skip to content

Commit 4830f58

Browse files
authored
bpo-29849: fix a memory leak in import_from (GH-712)
1 parent 05f5373 commit 4830f58

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- bpo-29849: Fix a memory leak when an ImportError is raised during from import.
14+
1315
- bpo-28856: Fix an oversight that %b format for bytes should support objects
1416
follow the buffer protocol.
1517

Python/ceval.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5024,7 +5024,7 @@ import_from(PyObject *v, PyObject *name)
50245024
{
50255025
PyObject *x;
50265026
_Py_IDENTIFIER(__name__);
5027-
PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown;
5027+
PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg;
50285028

50295029
x = PyObject_GetAttr(v, name);
50305030
if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
@@ -5039,6 +5039,7 @@ import_from(PyObject *v, PyObject *name)
50395039
}
50405040
fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name);
50415041
if (fullmodname == NULL) {
5042+
Py_DECREF(pkgname);
50425043
return NULL;
50435044
}
50445045
x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname);
@@ -5063,17 +5064,23 @@ import_from(PyObject *v, PyObject *name)
50635064

50645065
if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) {
50655066
PyErr_Clear();
5066-
PyErr_SetImportError(
5067-
PyUnicode_FromFormat("cannot import name %R from %R (unknown location)",
5068-
name, pkgname_or_unknown),
5069-
pkgname, NULL);
5070-
} else {
5071-
PyErr_SetImportError(
5072-
PyUnicode_FromFormat("cannot import name %R from %R (%S)",
5073-
name, pkgname_or_unknown, pkgpath),
5074-
pkgname, pkgpath);
5067+
errmsg = PyUnicode_FromFormat(
5068+
"cannot import name %R from %R (unknown location)",
5069+
name, pkgname_or_unknown
5070+
);
5071+
/* NULL check for errmsg done by PyErr_SetImportError. */
5072+
PyErr_SetImportError(errmsg, pkgname, NULL);
5073+
}
5074+
else {
5075+
errmsg = PyUnicode_FromFormat(
5076+
"cannot import name %R from %R (%S)",
5077+
name, pkgname_or_unknown, pkgpath
5078+
);
5079+
/* NULL check for errmsg done by PyErr_SetImportError. */
5080+
PyErr_SetImportError(errmsg, pkgname, pkgpath);
50755081
}
50765082

5083+
Py_XDECREF(errmsg);
50775084
Py_XDECREF(pkgname_or_unknown);
50785085
Py_XDECREF(pkgpath);
50795086
return NULL;

0 commit comments

Comments
 (0)