when an argument is a cell, set the local copy to NULL (see #17927)
This commit is contained in:
parent
3bfc5f5d83
commit
159ae41da6
|
@ -130,6 +130,19 @@ class TestSuper(unittest.TestCase):
|
|||
super()
|
||||
self.assertRaises(RuntimeError, X().f)
|
||||
|
||||
def test_cell_as_self(self):
|
||||
class X:
|
||||
def meth(self):
|
||||
super()
|
||||
|
||||
def f():
|
||||
k = X()
|
||||
def g():
|
||||
return k
|
||||
return g
|
||||
c = f().__closure__[0]
|
||||
self.assertRaises(TypeError, X.meth, c)
|
||||
|
||||
|
||||
def test_main():
|
||||
support.run_unittest(TestSuper)
|
||||
|
|
|
@ -6510,9 +6510,17 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return -1;
|
||||
}
|
||||
obj = f->f_localsplus[0];
|
||||
if (obj != NULL && PyCell_Check(obj)) {
|
||||
/* It might be a cell. See cell var initialization in ceval.c. */
|
||||
obj = PyCell_GET(obj);
|
||||
if (obj == NULL && co->co_cell2arg) {
|
||||
/* The first argument might be a cell. */
|
||||
n = PyTuple_GET_SIZE(co->co_cellvars);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (co->co_cell2arg[i] == 0) {
|
||||
PyObject *cell = f->f_localsplus[co->co_nlocals + i];
|
||||
assert(PyCell_Check(cell));
|
||||
obj = PyCell_GET(cell);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
|
|
|
@ -3521,18 +3521,14 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
|
|||
if (co->co_cell2arg != NULL &&
|
||||
(arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) {
|
||||
c = PyCell_New(GETLOCAL(arg));
|
||||
if (c == NULL)
|
||||
goto fail;
|
||||
/* Reference the cell from the argument slot, for super().
|
||||
See typeobject.c. */
|
||||
Py_INCREF(c);
|
||||
SETLOCAL(arg, c);
|
||||
/* Clear the local copy. */
|
||||
SETLOCAL(arg, NULL);
|
||||
}
|
||||
else {
|
||||
c = PyCell_New(NULL);
|
||||
if (c == NULL)
|
||||
goto fail;
|
||||
}
|
||||
if (c == NULL)
|
||||
goto fail;
|
||||
SETLOCAL(co->co_nlocals + i, c);
|
||||
}
|
||||
for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
|
||||
|
|
Loading…
Reference in New Issue