Skip to content

Commit 88f8102

Browse files
gh-132775: Support Fallbacks in _PyObject_GetXIData() (gh-133482)
It now supports a "full" fallback to _PyFunction_GetXIData() and then `_PyPickle_GetXIData()`. There's also room for other fallback modes if that later makes sense.
1 parent 0c5a8b0 commit 88f8102

11 files changed

+581
-139
lines changed

Include/internal/pycore_crossinterp.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,23 @@ PyAPI_FUNC(void) _PyXIData_Clear(PyInterpreterState *, _PyXIData_t *);
131131

132132
/* getting cross-interpreter data */
133133

134-
typedef int (*xidatafunc)(PyThreadState *tstate, PyObject *, _PyXIData_t *);
134+
typedef int xidata_fallback_t;
135+
#define _PyXIDATA_XIDATA_ONLY (0)
136+
#define _PyXIDATA_FULL_FALLBACK (1)
137+
138+
// Technically, we don't need two different function types;
139+
// we could go with just the fallback one. However, only container
140+
// types like tuple need it, so always having the extra arg would be
141+
// a bit unfortunate. It's also nice to be able to clearly distinguish
142+
// between types that might call _PyObject_GetXIData() and those that won't.
143+
//
144+
typedef int (*xidatafunc)(PyThreadState *, PyObject *, _PyXIData_t *);
145+
typedef int (*xidatafbfunc)(
146+
PyThreadState *, PyObject *, xidata_fallback_t, _PyXIData_t *);
147+
typedef struct {
148+
xidatafunc basic;
149+
xidatafbfunc fallback;
150+
} _PyXIData_getdata_t;
135151

136152
PyAPI_FUNC(PyObject *) _PyXIData_GetNotShareableErrorType(PyThreadState *);
137153
PyAPI_FUNC(void) _PyXIData_SetNotShareableError(PyThreadState *, const char *);
@@ -140,16 +156,21 @@ PyAPI_FUNC(void) _PyXIData_FormatNotShareableError(
140156
const char *,
141157
...);
142158

143-
PyAPI_FUNC(xidatafunc) _PyXIData_Lookup(
159+
PyAPI_FUNC(_PyXIData_getdata_t) _PyXIData_Lookup(
144160
PyThreadState *,
145161
PyObject *);
146162
PyAPI_FUNC(int) _PyObject_CheckXIData(
147163
PyThreadState *,
148164
PyObject *);
149165

166+
PyAPI_FUNC(int) _PyObject_GetXIDataNoFallback(
167+
PyThreadState *,
168+
PyObject *,
169+
_PyXIData_t *);
150170
PyAPI_FUNC(int) _PyObject_GetXIData(
151171
PyThreadState *,
152172
PyObject *,
173+
xidata_fallback_t,
153174
_PyXIData_t *);
154175

155176
// _PyObject_GetXIData() for bytes

Include/internal/pycore_crossinterp_data_registry.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ typedef struct _xid_regitem {
1717
/* This is NULL for builtin types. */
1818
PyObject *weakref;
1919
size_t refcount;
20-
xidatafunc getdata;
20+
_PyXIData_getdata_t getdata;
2121
} _PyXIData_regitem_t;
2222

2323
typedef struct {
@@ -30,7 +30,7 @@ typedef struct {
3030
PyAPI_FUNC(int) _PyXIData_RegisterClass(
3131
PyThreadState *,
3232
PyTypeObject *,
33-
xidatafunc);
33+
_PyXIData_getdata_t);
3434
PyAPI_FUNC(int) _PyXIData_UnregisterClass(
3535
PyThreadState *,
3636
PyTypeObject *);

Lib/test/support/import_helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,5 +438,5 @@ def ensure_module_imported(name, *, clearnone=True):
438438
if sys.modules.get(name) is not None:
439439
mod = sys.modules[name]
440440
else:
441-
mod, _, _ = _force_import(name, False, True, clearnone)
441+
mod, _, _ = _ensure_module(name, False, True, clearnone)
442442
return mod

0 commit comments

Comments
 (0)