mirror of https://github.com/python/cpython
Charles Waldman writes:
""" Running "test_extcall" repeatedly results in memory leaks. One of these can't be fixed (at least not easily!), it happens since this code: def saboteur(**kw): kw['x'] = locals() d = {} saboteur(a=1, **d) creates a circular reference - d['x']['d']==d The others are due to some missing decrefs in ceval.c, fixed by the patch attached below. Note: I originally wrote this without the "goto", just adding the missing decref's where needed. But I think the goto is justified in keeping the executable code size of ceval as small as possible. """ [I think the circular reference is more like kw['x']['kw'] == kw. --GvR]
This commit is contained in:
parent
5ce78f8e4e
commit
25826c93c4
|
@ -1623,8 +1623,7 @@ eval_code2(co, globals, locals,
|
||||||
if (!PyDict_Check(kwdict)) {
|
if (!PyDict_Check(kwdict)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"** argument must be a dictionary");
|
"** argument must be a dictionary");
|
||||||
x = NULL;
|
goto extcall_fail;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & 1) {
|
if (flags & 1) {
|
||||||
|
@ -1632,39 +1631,34 @@ eval_code2(co, globals, locals,
|
||||||
if (!PySequence_Check(stararg)) {
|
if (!PySequence_Check(stararg)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"* argument must be a sequence");
|
"* argument must be a sequence");
|
||||||
x = NULL;
|
goto extcall_fail;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
/* Convert abstract sequence to concrete tuple */
|
/* Convert abstract sequence to concrete tuple */
|
||||||
if (!PyTuple_Check(stararg)) {
|
if (!PyTuple_Check(stararg)) {
|
||||||
PyObject *t = NULL;
|
PyObject *t = NULL;
|
||||||
t = PySequence_Tuple(stararg);
|
t = PySequence_Tuple(stararg);
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
x = NULL;
|
goto extcall_fail;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Py_DECREF(stararg);
|
Py_DECREF(stararg);
|
||||||
stararg = t;
|
stararg = t;
|
||||||
}
|
}
|
||||||
nstar = PyTuple_GET_SIZE(stararg);
|
nstar = PyTuple_GET_SIZE(stararg);
|
||||||
if (nstar < 0) {
|
if (nstar < 0) {
|
||||||
x = NULL;
|
goto extcall_fail;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nk > 0) {
|
if (nk > 0) {
|
||||||
if (kwdict == NULL) {
|
if (kwdict == NULL) {
|
||||||
kwdict = PyDict_New();
|
kwdict = PyDict_New();
|
||||||
if (kwdict == NULL) {
|
if (kwdict == NULL) {
|
||||||
x = NULL;
|
goto extcall_fail;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *d = PyDict_Copy(kwdict);
|
PyObject *d = PyDict_Copy(kwdict);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
x = NULL;
|
goto extcall_fail;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Py_DECREF(kwdict);
|
Py_DECREF(kwdict);
|
||||||
kwdict = d;
|
kwdict = d;
|
||||||
|
@ -1680,7 +1674,7 @@ eval_code2(co, globals, locals,
|
||||||
PyString_AsString(key));
|
PyString_AsString(key));
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
break;
|
goto extcall_fail;
|
||||||
}
|
}
|
||||||
err = PyDict_SetItem(kwdict, key, value);
|
err = PyDict_SetItem(kwdict, key, value);
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
|
@ -1689,7 +1683,11 @@ eval_code2(co, globals, locals,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
Py_DECREF(kwdict);
|
extcall_fail:
|
||||||
|
Py_XDECREF(kwdict);
|
||||||
|
Py_XDECREF(stararg);
|
||||||
|
Py_DECREF(func);
|
||||||
|
x=NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2382,6 +2380,7 @@ PyEval_CallObjectWithKeywords(func, arg, kw)
|
||||||
if (kw != NULL && !PyDict_Check(kw)) {
|
if (kw != NULL && !PyDict_Check(kw)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"keyword list must be a dictionary");
|
"keyword list must be a dictionary");
|
||||||
|
Py_DECREF(arg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue