mirror of
https://github.com/python/cpython.git
synced 2025-08-02 08:02:56 +00:00
when an argument is a cell, set the local copy to NULL (see #17927)
This commit is contained in:
parent
3bfc5f5d83
commit
159ae41da6
3 changed files with 28 additions and 11 deletions
|
@ -130,6 +130,19 @@ class TestSuper(unittest.TestCase):
|
||||||
super()
|
super()
|
||||||
self.assertRaises(RuntimeError, X().f)
|
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():
|
def test_main():
|
||||||
support.run_unittest(TestSuper)
|
support.run_unittest(TestSuper)
|
||||||
|
|
|
@ -6510,9 +6510,17 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
obj = f->f_localsplus[0];
|
obj = f->f_localsplus[0];
|
||||||
if (obj != NULL && PyCell_Check(obj)) {
|
if (obj == NULL && co->co_cell2arg) {
|
||||||
/* It might be a cell. See cell var initialization in ceval.c. */
|
/* The first argument might be a cell. */
|
||||||
obj = PyCell_GET(obj);
|
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) {
|
if (obj == NULL) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
|
|
@ -3521,18 +3521,14 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
|
||||||
if (co->co_cell2arg != NULL &&
|
if (co->co_cell2arg != NULL &&
|
||||||
(arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) {
|
(arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) {
|
||||||
c = PyCell_New(GETLOCAL(arg));
|
c = PyCell_New(GETLOCAL(arg));
|
||||||
if (c == NULL)
|
/* Clear the local copy. */
|
||||||
goto fail;
|
SETLOCAL(arg, NULL);
|
||||||
/* Reference the cell from the argument slot, for super().
|
|
||||||
See typeobject.c. */
|
|
||||||
Py_INCREF(c);
|
|
||||||
SETLOCAL(arg, c);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = PyCell_New(NULL);
|
c = PyCell_New(NULL);
|
||||||
if (c == NULL)
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
if (c == NULL)
|
||||||
|
goto fail;
|
||||||
SETLOCAL(co->co_nlocals + i, c);
|
SETLOCAL(co->co_nlocals + i, c);
|
||||||
}
|
}
|
||||||
for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
|
for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue