diff options
-rw-r--r-- | Lib/test/test_code.py | 9 | ||||
-rw-r--r-- | Objects/codeobject.c | 8 |
2 files changed, 14 insertions, 3 deletions
diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 2bdd7e74943..9d6b465115c 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -320,6 +320,15 @@ class CodeTest(unittest.TestCase): with self.assertRaises(ValueError): co.replace(co_nlocals=co.co_nlocals + 1) + def test_shrinking_localsplus(self): + # Check that PyCode_NewWithPosOnlyArgs resizes both + # localsplusnames and localspluskinds, if an argument is a cell. + def func(arg): + return lambda: arg + code = func.__code__ + newcode = code.replace(co_name="func") # Should not raise SystemError + self.assertEqual(code, newcode) + def test_empty_linetable(self): def func(): pass diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 3dc9fd787f3..ad8f13a781b 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -471,9 +471,11 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, localsplusnames, localspluskinds); } // If any cells were args then nlocalsplus will have shrunk. - // We don't bother resizing localspluskinds. - if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0) { - goto error; + if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) { + if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0 + || _PyBytes_Resize(&localspluskinds, nlocalsplus) < 0) { + goto error; + } } struct _PyCodeConstructor con = { |