bpo-43693: Clean up the PyCodeObject fields. (GH-26364)

* Move up the comment about fields using in hashing/comparision.

* Group the fields more clearly.

* Add co_ncellvars and co_nfreevars.

* Raise ValueError if nlocals != len(varnames), rather than aborting.
This commit is contained in:
Eric Snow 2021-05-26 13:15:40 -06:00 committed by GitHub
parent e6c815d2e3
commit 6cc800d363
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 148 additions and 83 deletions

View file

@ -240,6 +240,7 @@ class CodeTest(unittest.TestCase):
# different co_name, co_varnames, co_consts
def func2():
y = 2
z = 3
return y
code2 = func2.__code__
@ -247,14 +248,14 @@ class CodeTest(unittest.TestCase):
("co_argcount", 0),
("co_posonlyargcount", 0),
("co_kwonlyargcount", 0),
("co_nlocals", 0),
("co_nlocals", 1),
("co_stacksize", 0),
("co_flags", code.co_flags | inspect.CO_COROUTINE),
("co_firstlineno", 100),
("co_code", code2.co_code),
("co_consts", code2.co_consts),
("co_names", ("myname",)),
("co_varnames", code2.co_varnames),
("co_varnames", ('spam',)),
("co_freevars", ("freevar",)),
("co_cellvars", ("cellvar",)),
("co_filename", "newfilename"),
@ -265,6 +266,47 @@ class CodeTest(unittest.TestCase):
new_code = code.replace(**{attr: value})
self.assertEqual(getattr(new_code, attr), value)
new_code = code.replace(co_varnames=code2.co_varnames,
co_nlocals=code2.co_nlocals)
self.assertEqual(new_code.co_varnames, code2.co_varnames)
self.assertEqual(new_code.co_nlocals, code2.co_nlocals)
def test_nlocals_mismatch(self):
def func():
x = 1
return x
co = func.__code__
assert co.co_nlocals > 0;
# First we try the constructor.
CodeType = type(co)
for diff in (-1, 1):
with self.assertRaises(ValueError):
CodeType(co.co_argcount,
co.co_posonlyargcount,
co.co_kwonlyargcount,
# This is the only change.
co.co_nlocals + diff,
co.co_stacksize,
co.co_flags,
co.co_code,
co.co_consts,
co.co_names,
co.co_varnames,
co.co_filename,
co.co_name,
co.co_firstlineno,
co.co_lnotab,
co.co_exceptiontable,
co.co_freevars,
co.co_cellvars,
)
# Then we try the replace method.
with self.assertRaises(ValueError):
co.replace(co_nlocals=co.co_nlocals - 1)
with self.assertRaises(ValueError):
co.replace(co_nlocals=co.co_nlocals + 1)
def test_empty_linetable(self):
def func():
pass