Fix a SystemError in code.replace() (#27771)

While the comment said 'We don't bother resizing localspluskinds',
this would cause .replace() to crash when it happened.
(Also types.CodeType(), but testing that is tedious, and this tests all
code paths.)
This commit is contained in:
Guido van Rossum 2021-08-16 11:34:23 -07:00 committed by GitHub
parent a0a6d39295
commit 62bd97303e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 3 deletions

View File

@ -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

View File

@ -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 = {