gh-132775: Add _PyCode_GetXIData() by ericsnowcurrently · Pull Request #133475 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add _PyCode_GetXIData().
  • Loading branch information
ericsnowcurrently committed May 5, 2025
commit ffdc68d0e01fd1ca0675bc82c3be8f3d8d93dfbb
7 changes: 7 additions & 0 deletions Include/internal/pycore_crossinterp.h
14 changes: 14 additions & 0 deletions Lib/test/_code_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ def spam_with_globals_and_builtins():
print(res)


def spam_args_attrs_and_builtins(a, b, /, c, d, *args, e, f, **kwargs):
if args.__len__() > 2:
return None
return a, b, c, d, e, f, args, kwargs


def spam_returns_arg(x):
return x

Expand All @@ -46,6 +52,10 @@ def eggs():
eggs()


def spam_annotated(a: int, b: str, c: object) -> tuple:
return a, b, c


def spam_full(a, b, /, c, d:int=1, *args, e, f:object=None, **kwargs) -> tuple:
# arg defaults, kwarg defaults
# annotations
Expand Down Expand Up @@ -134,9 +144,11 @@ def ham_C_closure(z):
spam_minimal,
spam_with_builtins,
spam_with_globals_and_builtins,
spam_args_attrs_and_builtins,
spam_returns_arg,
spam_with_inner_not_closure,
spam_with_inner_closure,
spam_annotated,
spam_full,
spam,
# outer func
Expand Down Expand Up @@ -170,7 +182,9 @@ def ham_C_closure(z):
spam,
spam_minimal,
spam_with_builtins,
spam_args_attrs_and_builtins,
spam_returns_arg,
spam_annotated,
spam_with_inner_not_closure,
spam_with_inner_closure,
spam_N,
Expand Down
26 changes: 26 additions & 0 deletions Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,16 @@ def test_local_kinds(self):
'checks': CO_FAST_LOCAL,
'res': CO_FAST_LOCAL,
},
defs.spam_args_attrs_and_builtins: {
'a': POSONLY,
'b': POSONLY,
'c': POSORKW,
'd': POSORKW,
'e': KWONLY,
'f': KWONLY,
'args': VARARGS,
'kwargs': VARKWARGS,
},
defs.spam_returns_arg: {
'x': POSORKW,
},
Expand All @@ -697,6 +707,11 @@ def test_local_kinds(self):
'x': CO_FAST_CELL,
'eggs': CO_FAST_LOCAL,
},
defs.spam_annotated: {
'a': POSORKW,
'b': POSORKW,
'c': POSORKW,
},
defs.spam_full: {
'a': POSONLY,
'b': POSONLY,
Expand Down Expand Up @@ -892,6 +907,14 @@ def new_var_counts(*,
purelocals=5,
globalvars=6,
),
defs.spam_args_attrs_and_builtins: new_var_counts(
posonly=2,
posorkw=2,
kwonly=2,
varargs=1,
varkwargs=1,
attrs=1,
),
defs.spam_returns_arg: new_var_counts(
posorkw=1,
),
Expand All @@ -902,6 +925,9 @@ def new_var_counts(*,
othercells=1,
purelocals=1,
),
defs.spam_annotated: new_var_counts(
posorkw=3,
),
defs.spam_full: new_var_counts(
posonly=2,
posorkw=2,
Expand Down
46 changes: 40 additions & 6 deletions Lib/test/test_crossinterp.py
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,39 @@ def test_user_exception(self):
])


class CodeTests(_GetXIDataTests):

MODE = 'code'

def test_function_code(self):
self.assert_roundtrip_equal_not_identical([
*(f.__code__ for f in defs.FUNCTIONS),
*(f.__code__ for f in defs.FUNCTION_LIKE),
])

def test_functions(self):
self.assert_not_shareable([
*defs.FUNCTIONS,
*defs.FUNCTION_LIKE,
])

def test_other_objects(self):
self.assert_not_shareable([
None,
True,
False,
Ellipsis,
NotImplemented,
9999,
'spam',
b'spam',
(),
[],
{},
object(),
])


class ShareableTypeTests(_GetXIDataTests):

MODE = 'xidata'
Expand Down Expand Up @@ -817,6 +850,13 @@ def test_object(self):
object(),
])

def test_code(self):
# types.CodeType
self.assert_not_shareable([
*(f.__code__ for f in defs.FUNCTIONS),
*(f.__code__ for f in defs.FUNCTION_LIKE),
])

def test_function_object(self):
for func in defs.FUNCTIONS:
assert type(func) is types.FunctionType, func
Expand Down Expand Up @@ -935,12 +975,6 @@ def test_builtin_objects(self):
self.assert_not_shareable([
types.MappingProxyType({}),
types.SimpleNamespace(),
# types.CodeType
defs.spam_minimal.__code__,
defs.spam_full.__code__,
defs.spam_CC.__code__,
defs.eggs_closure_C.__code__,
defs.ham_C_closure.__code__,
# types.CellType
types.CellType(),
# types.FrameType
Expand Down
5 changes: 5 additions & 0 deletions Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1991,6 +1991,11 @@ get_crossinterp_data(PyObject *self, PyObject *args, PyObject *kwargs)
goto error;
}
}
else if (strcmp(mode, "code") == 0) {
if (_PyCode_GetXIData(tstate, obj, xidata) != 0) {
goto error;
}
}
else {
PyErr_Format(PyExc_ValueError, "unsupported mode %R", modeobj);
goto error;
Expand Down
24 changes: 24 additions & 0 deletions Python/crossinterp_data_lookup.h