aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_code.py9
-rw-r--r--Objects/codeobject.c8
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 = {