Skip to content

Commit b943bb0

Browse files
Add a test for co_extra.
1 parent c36747c commit b943bb0

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

Lib/test/test_code.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,18 @@ def test_stateless(self):
10881088
with self.assertRaises(Exception):
10891089
_testinternalcapi.verify_stateless_code(func)
10901090

1091+
def spam():
1092+
pass
1093+
1094+
with self.subTest('with co_extra'):
1095+
_testinternalcapi.verify_stateless_code(spam)
1096+
extra = 'spam'
1097+
_testinternalcapi.code_set_co_extra(spam.__code__, 0, extra)
1098+
with self.assertRaises(ValueError):
1099+
_testinternalcapi.verify_stateless_code(spam)
1100+
_testinternalcapi.code_set_co_extra(spam.__code__, 0, expect=extra)
1101+
_testinternalcapi.verify_stateless_code(spam)
1102+
10911103

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

Modules/_testinternalcapi.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,58 @@ verify_stateless_code(PyObject *self, PyObject *args, PyObject *kwargs)
12061206
Py_RETURN_NONE;
12071207
}
12081208

1209+
static PyObject *
1210+
code_set_co_extra(PyObject *self, PyObject *args, PyObject *kwargs)
1211+
{
1212+
PyObject *codearg;
1213+
Py_ssize_t index;
1214+
PyObject *value = NULL;
1215+
PyObject *expected = NULL;
1216+
PyObject *notset = Py_None;
1217+
static char *kwlist[] =
1218+
{"code", "index", "value", "expect", "notset", NULL};
1219+
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1220+
"O!n|OOO:code_set_co_extra", kwlist,
1221+
&PyCode_Type, &codearg, &index, &value, &expected, &notset))
1222+
{
1223+
return NULL;
1224+
}
1225+
1226+
void *extra;
1227+
if (PyUnstable_Code_GetExtra(codearg, index, &extra) < 0) {
1228+
return NULL;
1229+
}
1230+
1231+
PyObject *old;
1232+
if (extra == NULL) {
1233+
old = Py_NewRef(notset);
1234+
}
1235+
else if (extra == expected) {
1236+
old = Py_NewRef(expected);
1237+
}
1238+
else if (extra == value) {
1239+
old = Py_NewRef(value);
1240+
}
1241+
else {
1242+
if (expected == NULL) {
1243+
PyErr_SetString(PyExc_ValueError,
1244+
"expected existing co_extra to be NULL");
1245+
}
1246+
else {
1247+
PyErr_Format(PyExc_ValueError,
1248+
"expected existing co_extra to be %R", expected);
1249+
}
1250+
return NULL;
1251+
}
1252+
1253+
if (PyUnstable_Code_SetExtra(codearg, index, value) < 0) {
1254+
Py_DECREF(old);
1255+
return NULL;
1256+
}
1257+
1258+
return old;
1259+
}
1260+
12091261
#ifdef _Py_TIER2
12101262

12111263
static PyObject *
@@ -2335,6 +2387,8 @@ static PyMethodDef module_functions[] = {
23352387
METH_VARARGS | METH_KEYWORDS, NULL},
23362388
{"verify_stateless_code", _PyCFunction_CAST(verify_stateless_code),
23372389
METH_VARARGS | METH_KEYWORDS, NULL},
2390+
{"code_set_co_extra", _PyCFunction_CAST(code_set_co_extra),
2391+
METH_VARARGS | METH_KEYWORDS, NULL},
23382392
#ifdef _Py_TIER2
23392393
{"add_executor_dependency", add_executor_dependency, METH_VARARGS, NULL},
23402394
{"invalidate_executors", invalidate_executors, METH_O, NULL},

0 commit comments

Comments
 (0)