gh-132775: Unrevert "Add _PyCode_VerifyStateless()" (gh-133528) · python/cpython@27128e4 · GitHub
Skip to content

Commit 27128e4

Browse files
gh-132775: Unrevert "Add _PyCode_VerifyStateless()" (gh-133528)
This reverts commit 3c73cf5 (gh-133497), which itself reverted the original commit d270bb5 (gh-133221). We reverted the original change due to failing android tests. The checks in _PyCode_CheckNoInternalState() were too strict, so we've relaxed them.
1 parent 61ac88c commit 27128e4

8 files changed

Lines changed: 358 additions & 37 deletions

File tree

Include/internal/pycore_code.h

Lines changed: 41 additions & 0 deletions

Include/internal/pycore_function.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ PyFunctionObject *_PyFunction_LookupByVersion(uint32_t version, PyObject **p_cod
3535
extern PyObject *_Py_set_function_type_params(
3636
PyThreadState* unused, PyObject *func, PyObject *type_params);
3737

38+
39+
/* See pycore_code.h for explanation about what "stateless" means. */
40+
41+
PyAPI_FUNC(int)
42+
_PyFunction_VerifyStateless(PyThreadState *, PyObject *);
43+
44+
3845
#ifdef __cplusplus
3946
}
4047
#endif

Include/internal/pycore_opcode_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ extern "C" {
5656

5757
#define IS_RETURN_OPCODE(opcode) \
5858
(opcode == RETURN_VALUE)
59+
#define IS_RAISE_OPCODE(opcode) \
60+
(opcode == RAISE_VARARGS || opcode == RERAISE)
5961

6062

6163
/* Flags used in the oparg for MAKE_FUNCTION */

Lib/test/_code_definitions.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,32 @@ def ham_C_closure(z):
178178
*NESTED_FUNCTIONS,
179179
]
180180

181+
STATELESS_FUNCTIONS = [
182+
spam,
183+
spam_minimal,
184+
spam_with_builtins,
185+
spam_args_attrs_and_builtins,
186+
spam_returns_arg,
187+
spam_annotated,
188+
spam_with_inner_not_closure,
189+
spam_with_inner_closure,
190+
spam_N,
191+
spam_C,
192+
spam_NN,
193+
spam_NC,
194+
spam_CN,
195+
spam_CC,
196+
eggs_nested,
197+
eggs_nested_N,
198+
ham_nested,
199+
ham_C_nested
200+
]
201+
STATELESS_CODE = [
202+
*STATELESS_FUNCTIONS,
203+
spam_with_globals_and_builtins,
204+
spam_full,
205+
]
206+
181207

182208
# generators
183209

Lib/test/test_code.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@
220220
import _testinternalcapi
221221
except ModuleNotFoundError:
222222
_testinternalcapi = None
223+
import test._code_definitions as defs
223224

224225
COPY_FREE_VARS = opmap['COPY_FREE_VARS']
225226

@@ -671,7 +672,6 @@ def test_local_kinds(self):
671672
VARARGS = CO_FAST_LOCAL | CO_FAST_ARG_VAR | CO_FAST_ARG_POS
672673
VARKWARGS = CO_FAST_LOCAL | CO_FAST_ARG_VAR | CO_FAST_ARG_KW
673674

674-
import test._code_definitions as defs
675675
funcs = {
676676
defs.spam_minimal: {},
677677
defs.spam_with_builtins: {
@@ -897,7 +897,6 @@ def new_var_counts(*,
897897
},
898898
}
899899

900-
import test._code_definitions as defs
901900
funcs = {
902901
defs.spam_minimal: new_var_counts(),
903902
defs.spam_with_builtins: new_var_counts(
@@ -1025,55 +1024,70 @@ def new_var_counts(*,
10251024
counts = _testinternalcapi.get_code_var_counts(func.__code__)
10261025
self.assertEqual(counts, expected)
10271026

1028-
def func_with_globals_and_builtins():
1029-
mod1 = _testinternalcapi
1030-
mod2 = dis
1031-
mods = (mod1, mod2)
1032-
checks = tuple(callable(m) for m in mods)
1033-
return callable(mod2), tuple(mods), list(mods), checks
1034-
1035-
func = func_with_globals_and_builtins
1027+
func = defs.spam_with_globals_and_builtins
10361028
with self.subTest(f'{func} code'):
10371029
expected = new_var_counts(
1038-
purelocals=4,
1039-
globalvars=5,
1030+
purelocals=5,
1031+
globalvars=6,
10401032
)
10411033
counts = _testinternalcapi.get_code_var_counts(func.__code__)
10421034
self.assertEqual(counts, expected)
10431035

10441036
with self.subTest(f'{func} with own globals and builtins'):
10451037
expected = new_var_counts(
1046-
purelocals=4,
1047-
globalvars=(2, 3),
1038+
purelocals=5,
1039+
globalvars=(2, 4),
10481040
)
10491041
counts = _testinternalcapi.get_code_var_counts(func)
10501042
self.assertEqual(counts, expected)
10511043

10521044
with self.subTest(f'{func} without globals'):
10531045
expected = new_var_counts(
1054-
purelocals=4,
1055-
globalvars=(0, 3, 2),
1046+
purelocals=5,
1047+
globalvars=(0, 4, 2),
10561048
)
10571049
counts = _testinternalcapi.get_code_var_counts(func, globalsns={})
10581050
self.assertEqual(counts, expected)
10591051

10601052
with self.subTest(f'{func} without both'):
10611053
expected = new_var_counts(
1062-
purelocals=4,
1063-
globalvars=5,
1054+
purelocals=5,
1055+
globalvars=6,
10641056
)
10651057
counts = _testinternalcapi.get_code_var_counts(func, globalsns={},
10661058
builtinsns={})
10671059
self.assertEqual(counts, expected)
10681060

10691061
with self.subTest(f'{func} without builtins'):
10701062
expected = new_var_counts(
1071-
purelocals=4,
1072-
globalvars=(2, 0, 3),
1063+
purelocals=5,
1064+
globalvars=(2, 0, 4),
10731065
)
10741066
counts = _testinternalcapi.get_code_var_counts(func, builtinsns={})
10751067
self.assertEqual(counts, expected)
10761068

1069+
@unittest.skipIf(_testinternalcapi is None, "missing _testinternalcapi")
1070+
def test_stateless(self):
1071+
self.maxDiff = None
1072+
1073+
for func in defs.STATELESS_CODE:
1074+
with self.subTest((func, '(code)')):
1075+
_testinternalcapi.verify_stateless_code(func.__code__)
1076+
for func in defs.STATELESS_FUNCTIONS:
1077+
with self.subTest((func, '(func)')):
1078+
_testinternalcapi.verify_stateless_code(func)
1079+
1080+
for func in defs.FUNCTIONS:
1081+
if func not in defs.STATELESS_CODE:
1082+
with self.subTest((func, '(code)')):
1083+
with self.assertRaises(Exception):
1084+
_testinternalcapi.verify_stateless_code(func.__code__)
1085+
1086+
if func not in defs.STATELESS_FUNCTIONS:
1087+
with self.subTest((func, '(func)')):
1088+
with self.assertRaises(Exception):
1089+
_testinternalcapi.verify_stateless_code(func)
1090+
10771091

10781092
def isinterned(s):
10791093
return s is sys.intern(('_' + s + '_')[1:-1])

Modules/_testinternalcapi.c

Lines changed: 43 additions & 0 deletions

0 commit comments

Comments
 (0)