Skip to content

Commit

Permalink
Fix a SystemError in code.replace() (python#27771)
Browse files Browse the repository at this point in the history
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.)
  • Loading branch information
gvanrossum committed Aug 16, 2021
1 parent a0a6d39 commit 62bd973
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
9 changes: 9 additions & 0 deletions Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,15 @@ def func():
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
Expand Down
8 changes: 5 additions & 3 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down

0 comments on commit 62bd973

Please sign in to comment.