Skip to content

Commit e7d7e26

Browse files
committed
Revert "gh-132775: Add _PyCode_VerifyStateless() (gh-133221)"
This reverts commit d270bb5. Note that the test functions in _code_definitions are not reverted.
1 parent 120c9d4 commit e7d7e26

File tree

8 files changed

+37
-362
lines changed

8 files changed

+37
-362
lines changed

Include/internal/pycore_code.h

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -619,47 +619,6 @@ PyAPI_FUNC(int) _PyCode_SetUnboundVarCounts(
619619
PyObject *globalsns,
620620
PyObject *builtinsns);
621621

622-
623-
/* "Stateless" code is a function or code object which does not rely on
624-
* external state or internal state. It may rely on arguments and
625-
* builtins, but not globals or a closure. Thus it does not rely
626-
* on __globals__ or __closure__, and a stateless function
627-
* is equivalent to its code object.
628-
*
629-
* Stateless code also does not keep any persistent state
630-
* of its own, so it can't have any executors, monitoring,
631-
* instrumentation, or "extras" (i.e. co_extra).
632-
*
633-
* Stateless code may create nested functions, including closures.
634-
* However, nested functions must themselves be stateless, except they
635-
* *can* close on the enclosing locals.
636-
*
637-
* Stateless code may return any value, including nested functions and closures.
638-
*
639-
* Stateless code that takes no arguments and doesn't return anything
640-
* may be treated like a script.
641-
*
642-
* We consider stateless code to be "portable" if it does not return any
643-
* any object that holds a reference to any of the code's locals. Thus
644-
* generators and coroutines are not portable. Likewise a function
645-
* that returns a closure is not portable. The concept of
646-
* portability is useful in cases where the code is run
647-
* in a different execution context than where
648-
* the return value will be used. */
649-
650-
PyAPI_FUNC(int) _PyCode_CheckNoInternalState(PyCodeObject *, const char **);
651-
PyAPI_FUNC(int) _PyCode_CheckNoExternalState(
652-
PyCodeObject *,
653-
_PyCode_var_counts_t *,
654-
const char **);
655-
PyAPI_FUNC(int) _PyCode_VerifyStateless(
656-
PyThreadState *,
657-
PyCodeObject *,
658-
PyObject *globalnames,
659-
PyObject *globalsns,
660-
PyObject *builtinsns);
661-
662-
PyAPI_FUNC(int) _PyCode_CheckPureFunction(PyCodeObject *, const char **);
663622
PyAPI_FUNC(int) _PyCode_ReturnsOnlyNone(PyCodeObject *);
664623

665624

Include/internal/pycore_function.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,6 @@ 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-
4538
#ifdef __cplusplus
4639
}
4740
#endif

Include/internal/pycore_opcode_utils.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ 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)
6159

6260

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

Lib/test/_code_definitions.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -178,32 +178,6 @@ 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-
207181

208182
# generators
209183

Lib/test/test_code.py

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

225224
COPY_FREE_VARS = opmap['COPY_FREE_VARS']
226225

@@ -672,6 +671,7 @@ def test_local_kinds(self):
672671
VARARGS = CO_FAST_LOCAL | CO_FAST_ARG_VAR | CO_FAST_ARG_POS
673672
VARKWARGS = CO_FAST_LOCAL | CO_FAST_ARG_VAR | CO_FAST_ARG_KW
674673

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

900+
import test._code_definitions as defs
900901
funcs = {
901902
defs.spam_minimal: new_var_counts(),
902903
defs.spam_with_builtins: new_var_counts(
@@ -1024,70 +1025,55 @@ def new_var_counts(*,
10241025
counts = _testinternalcapi.get_code_var_counts(func.__code__)
10251026
self.assertEqual(counts, expected)
10261027

1027-
func = defs.spam_with_globals_and_builtins
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
10281036
with self.subTest(f'{func} code'):
10291037
expected = new_var_counts(
1030-
purelocals=5,
1031-
globalvars=6,
1038+
purelocals=4,
1039+
globalvars=5,
10321040
)
10331041
counts = _testinternalcapi.get_code_var_counts(func.__code__)
10341042
self.assertEqual(counts, expected)
10351043

10361044
with self.subTest(f'{func} with own globals and builtins'):
10371045
expected = new_var_counts(
1038-
purelocals=5,
1039-
globalvars=(2, 4),
1046+
purelocals=4,
1047+
globalvars=(2, 3),
10401048
)
10411049
counts = _testinternalcapi.get_code_var_counts(func)
10421050
self.assertEqual(counts, expected)
10431051

10441052
with self.subTest(f'{func} without globals'):
10451053
expected = new_var_counts(
1046-
purelocals=5,
1047-
globalvars=(0, 4, 2),
1054+
purelocals=4,
1055+
globalvars=(0, 3, 2),
10481056
)
10491057
counts = _testinternalcapi.get_code_var_counts(func, globalsns={})
10501058
self.assertEqual(counts, expected)
10511059

10521060
with self.subTest(f'{func} without both'):
10531061
expected = new_var_counts(
1054-
purelocals=5,
1055-
globalvars=6,
1062+
purelocals=4,
1063+
globalvars=5,
10561064
)
10571065
counts = _testinternalcapi.get_code_var_counts(func, globalsns={},
10581066
builtinsns={})
10591067
self.assertEqual(counts, expected)
10601068

10611069
with self.subTest(f'{func} without builtins'):
10621070
expected = new_var_counts(
1063-
purelocals=5,
1064-
globalvars=(2, 0, 4),
1071+
purelocals=4,
1072+
globalvars=(2, 0, 3),
10651073
)
10661074
counts = _testinternalcapi.get_code_var_counts(func, builtinsns={})
10671075
self.assertEqual(counts, expected)
10681076

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-
10911077

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

Modules/_testinternalcapi.c

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,47 +1165,6 @@ get_code_var_counts(PyObject *self, PyObject *_args, PyObject *_kwargs)
11651165
return NULL;
11661166
}
11671167

1168-
static PyObject *
1169-
verify_stateless_code(PyObject *self, PyObject *args, PyObject *kwargs)
1170-
{
1171-
PyThreadState *tstate = _PyThreadState_GET();
1172-
PyObject *codearg;
1173-
PyObject *globalnames = NULL;
1174-
PyObject *globalsns = NULL;
1175-
PyObject *builtinsns = NULL;
1176-
static char *kwlist[] = {"code", "globalnames",
1177-
"globalsns", "builtinsns", NULL};
1178-
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1179-
"O|O!O!O!:get_code_var_counts", kwlist,
1180-
&codearg, &PySet_Type, &globalnames,
1181-
&PyDict_Type, &globalsns, &PyDict_Type, &builtinsns))
1182-
{
1183-
return NULL;
1184-
}
1185-
if (PyFunction_Check(codearg)) {
1186-
if (globalsns == NULL) {
1187-
globalsns = PyFunction_GET_GLOBALS(codearg);
1188-
}
1189-
if (builtinsns == NULL) {
1190-
builtinsns = PyFunction_GET_BUILTINS(codearg);
1191-
}
1192-
codearg = PyFunction_GET_CODE(codearg);
1193-
}
1194-
else if (!PyCode_Check(codearg)) {
1195-
PyErr_SetString(PyExc_TypeError,
1196-
"argument must be a code object or a function");
1197-
return NULL;
1198-
}
1199-
PyCodeObject *code = (PyCodeObject *)codearg;
1200-
1201-
if (_PyCode_VerifyStateless(
1202-
tstate, code, globalnames, globalsns, builtinsns) < 0)
1203-
{
1204-
return NULL;
1205-
}
1206-
Py_RETURN_NONE;
1207-
}
1208-
12091168
#ifdef _Py_TIER2
12101169

12111170
static PyObject *
@@ -2333,8 +2292,6 @@ static PyMethodDef module_functions[] = {
23332292
{"get_co_localskinds", get_co_localskinds, METH_O, NULL},
23342293
{"get_code_var_counts", _PyCFunction_CAST(get_code_var_counts),
23352294
METH_VARARGS | METH_KEYWORDS, NULL},
2336-
{"verify_stateless_code", _PyCFunction_CAST(verify_stateless_code),
2337-
METH_VARARGS | METH_KEYWORDS, NULL},
23382295
#ifdef _Py_TIER2
23392296
{"add_executor_dependency", add_executor_dependency, METH_VARARGS, NULL},
23402297
{"invalidate_executors", invalidate_executors, METH_O, NULL},

0 commit comments

Comments
 (0)