mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-132775: Unrevert "Add _PyCode_GetVarCounts()" (gh-133265)
This reverts commit811edcf
(gh-133232), which itself reverted the original commit811edcf
(gh-133128). We reverted the original change due to failing s390 builds (a big-endian architecture). It ended up that I had not accommodated op caches.
This commit is contained in:
parent
b275b8f342
commit
24ebb9ccfd
5 changed files with 732 additions and 3 deletions
|
@ -777,6 +777,236 @@ class CodeTest(unittest.TestCase):
|
|||
kinds = _testinternalcapi.get_co_localskinds(func.__code__)
|
||||
self.assertEqual(kinds, expected)
|
||||
|
||||
@unittest.skipIf(_testinternalcapi is None, "missing _testinternalcapi")
|
||||
def test_var_counts(self):
|
||||
self.maxDiff = None
|
||||
def new_var_counts(*,
|
||||
posonly=0,
|
||||
posorkw=0,
|
||||
kwonly=0,
|
||||
varargs=0,
|
||||
varkwargs=0,
|
||||
purelocals=0,
|
||||
argcells=0,
|
||||
othercells=0,
|
||||
freevars=0,
|
||||
globalvars=0,
|
||||
attrs=0,
|
||||
unknown=0,
|
||||
):
|
||||
nargvars = posonly + posorkw + kwonly + varargs + varkwargs
|
||||
nlocals = nargvars + purelocals + othercells
|
||||
if isinstance(globalvars, int):
|
||||
globalvars = {
|
||||
'total': globalvars,
|
||||
'numglobal': 0,
|
||||
'numbuiltin': 0,
|
||||
'numunknown': globalvars,
|
||||
}
|
||||
else:
|
||||
g_numunknown = 0
|
||||
if isinstance(globalvars, dict):
|
||||
numglobal = globalvars['numglobal']
|
||||
numbuiltin = globalvars['numbuiltin']
|
||||
size = 2
|
||||
if 'numunknown' in globalvars:
|
||||
g_numunknown = globalvars['numunknown']
|
||||
size += 1
|
||||
assert len(globalvars) == size, globalvars
|
||||
else:
|
||||
assert not isinstance(globalvars, str), repr(globalvars)
|
||||
try:
|
||||
numglobal, numbuiltin = globalvars
|
||||
except ValueError:
|
||||
numglobal, numbuiltin, g_numunknown = globalvars
|
||||
globalvars = {
|
||||
'total': numglobal + numbuiltin + g_numunknown,
|
||||
'numglobal': numglobal,
|
||||
'numbuiltin': numbuiltin,
|
||||
'numunknown': g_numunknown,
|
||||
}
|
||||
unbound = globalvars['total'] + attrs + unknown
|
||||
return {
|
||||
'total': nlocals + freevars + unbound,
|
||||
'locals': {
|
||||
'total': nlocals,
|
||||
'args': {
|
||||
'total': nargvars,
|
||||
'numposonly': posonly,
|
||||
'numposorkw': posorkw,
|
||||
'numkwonly': kwonly,
|
||||
'varargs': varargs,
|
||||
'varkwargs': varkwargs,
|
||||
},
|
||||
'numpure': purelocals,
|
||||
'cells': {
|
||||
'total': argcells + othercells,
|
||||
'numargs': argcells,
|
||||
'numothers': othercells,
|
||||
},
|
||||
'hidden': {
|
||||
'total': 0,
|
||||
'numpure': 0,
|
||||
'numcells': 0,
|
||||
},
|
||||
},
|
||||
'numfree': freevars,
|
||||
'unbound': {
|
||||
'total': unbound,
|
||||
'globals': globalvars,
|
||||
'numattrs': attrs,
|
||||
'numunknown': unknown,
|
||||
},
|
||||
}
|
||||
|
||||
import test._code_definitions as defs
|
||||
funcs = {
|
||||
defs.spam_minimal: new_var_counts(),
|
||||
defs.spam_full: new_var_counts(
|
||||
posonly=2,
|
||||
posorkw=2,
|
||||
kwonly=2,
|
||||
varargs=1,
|
||||
varkwargs=1,
|
||||
purelocals=4,
|
||||
globalvars=3,
|
||||
attrs=1,
|
||||
),
|
||||
defs.spam: new_var_counts(
|
||||
posorkw=1,
|
||||
),
|
||||
defs.spam_N: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
),
|
||||
defs.spam_C: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
argcells=1,
|
||||
othercells=1,
|
||||
),
|
||||
defs.spam_NN: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
),
|
||||
defs.spam_NC: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
argcells=1,
|
||||
othercells=1,
|
||||
),
|
||||
defs.spam_CN: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
argcells=1,
|
||||
othercells=1,
|
||||
),
|
||||
defs.spam_CC: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
argcells=1,
|
||||
othercells=1,
|
||||
),
|
||||
defs.eggs_nested: new_var_counts(
|
||||
posorkw=1,
|
||||
),
|
||||
defs.eggs_closure: new_var_counts(
|
||||
posorkw=1,
|
||||
freevars=2,
|
||||
),
|
||||
defs.eggs_nested_N: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
),
|
||||
defs.eggs_nested_C: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
argcells=1,
|
||||
freevars=2,
|
||||
),
|
||||
defs.eggs_closure_N: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
freevars=2,
|
||||
),
|
||||
defs.eggs_closure_C: new_var_counts(
|
||||
posorkw=1,
|
||||
purelocals=1,
|
||||
argcells=1,
|
||||
othercells=1,
|
||||
freevars=2,
|
||||
),
|
||||
defs.ham_nested: new_var_counts(
|
||||
posorkw=1,
|
||||
),
|
||||
defs.ham_closure: new_var_counts(
|
||||
posorkw=1,
|
||||
freevars=3,
|
||||
),
|
||||
defs.ham_C_nested: new_var_counts(
|
||||
posorkw=1,
|
||||
),
|
||||
defs.ham_C_closure: new_var_counts(
|
||||
posorkw=1,
|
||||
freevars=4,
|
||||
),
|
||||
}
|
||||
assert len(funcs) == len(defs.FUNCTIONS), (len(funcs), len(defs.FUNCTIONS))
|
||||
for func in defs.FUNCTIONS:
|
||||
with self.subTest(func):
|
||||
expected = funcs[func]
|
||||
counts = _testinternalcapi.get_code_var_counts(func.__code__)
|
||||
self.assertEqual(counts, expected)
|
||||
|
||||
def func_with_globals_and_builtins():
|
||||
mod1 = _testinternalcapi
|
||||
mod2 = dis
|
||||
mods = (mod1, mod2)
|
||||
checks = tuple(callable(m) for m in mods)
|
||||
return callable(mod2), tuple(mods), list(mods), checks
|
||||
|
||||
func = func_with_globals_and_builtins
|
||||
with self.subTest(f'{func} code'):
|
||||
expected = new_var_counts(
|
||||
purelocals=4,
|
||||
globalvars=5,
|
||||
)
|
||||
counts = _testinternalcapi.get_code_var_counts(func.__code__)
|
||||
self.assertEqual(counts, expected)
|
||||
|
||||
with self.subTest(f'{func} with own globals and builtins'):
|
||||
expected = new_var_counts(
|
||||
purelocals=4,
|
||||
globalvars=(2, 3),
|
||||
)
|
||||
counts = _testinternalcapi.get_code_var_counts(func)
|
||||
self.assertEqual(counts, expected)
|
||||
|
||||
with self.subTest(f'{func} without globals'):
|
||||
expected = new_var_counts(
|
||||
purelocals=4,
|
||||
globalvars=(0, 3, 2),
|
||||
)
|
||||
counts = _testinternalcapi.get_code_var_counts(func, globalsns={})
|
||||
self.assertEqual(counts, expected)
|
||||
|
||||
with self.subTest(f'{func} without both'):
|
||||
expected = new_var_counts(
|
||||
purelocals=4,
|
||||
globalvars=5,
|
||||
)
|
||||
counts = _testinternalcapi.get_code_var_counts(func, globalsns={},
|
||||
builtinsns={})
|
||||
self.assertEqual(counts, expected)
|
||||
|
||||
with self.subTest(f'{func} without builtins'):
|
||||
expected = new_var_counts(
|
||||
purelocals=4,
|
||||
globalvars=(2, 0, 3),
|
||||
)
|
||||
counts = _testinternalcapi.get_code_var_counts(func, builtinsns={})
|
||||
self.assertEqual(counts, expected)
|
||||
|
||||
|
||||
def isinterned(s):
|
||||
return s is sys.intern(('_' + s + '_')[1:-1])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue