Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/python3.14/internal/pycore_crossinterp.h
1 #ifndef Py_INTERNAL_CROSSINTERP_H 2 #define Py_INTERNAL_CROSSINTERP_H 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #ifndef Py_BUILD_CORE 8 # error "this header requires Py_BUILD_CORE define" 9 #endif 10 11 #include "pycore_pyerrors.h" 12 13 14 /**************/ 15 /* exceptions */ 16 /**************/ 17 18 PyAPI_DATA(PyObject *) PyExc_InterpreterError; 19 PyAPI_DATA(PyObject *) PyExc_InterpreterNotFoundError; 20 21 22 /***************************/ 23 /* cross-interpreter calls */ 24 /***************************/ 25 26 typedef int (*_Py_simple_func)(void *); 27 extern int _Py_CallInInterpreter( 28 PyInterpreterState *interp, 29 _Py_simple_func func, 30 void *arg); 31 extern int _Py_CallInInterpreterAndRawFree( 32 PyInterpreterState *interp, 33 _Py_simple_func func, 34 void *arg); 35 36 37 /**************************/ 38 /* cross-interpreter data */ 39 /**************************/ 40 41 typedef struct _xidata _PyXIData_t; 42 typedef PyObject *(*xid_newobjfunc)(_PyXIData_t *); 43 typedef void (*xid_freefunc)(void *); 44 45 // _PyXIData_t is similar to Py_buffer as an effectively 46 // opaque struct that holds data outside the object machinery. This 47 // is necessary to pass safely between interpreters in the same process. 48 struct _xidata { 49 // data is the cross-interpreter-safe derivation of a Python object 50 // (see _PyObject_GetXIData). It will be NULL if the 51 // new_object func (below) encodes the data. 52 void *data; 53 // obj is the Python object from which the data was derived. This 54 // is non-NULL only if the data remains bound to the object in some 55 // way, such that the object must be "released" (via a decref) when 56 // the data is released. In that case the code that sets the field, 57 // likely a registered "xidatafunc", is responsible for 58 // ensuring it owns the reference (i.e. incref). 59 PyObject *obj; 60 // interpid is the ID of the owning interpreter of the original 61 // object. It corresponds to the active interpreter when 62 // _PyObject_GetXIData() was called. This should only 63 // be set by the cross-interpreter machinery. 64 // 65 // We use the ID rather than the PyInterpreterState to avoid issues 66 // with deleted interpreters. Note that IDs are never re-used, so 67 // each one will always correspond to a specific interpreter 68 // (whether still alive or not). 69 int64_t interpid; 70 // new_object is a function that returns a new object in the current 71 // interpreter given the data. The resulting object (a new 72 // reference) will be equivalent to the original object. This field 73 // is required. 74 xid_newobjfunc new_object; 75 // free is called when the data is released. If it is NULL then 76 // nothing will be done to free the data. For some types this is 77 // okay (e.g. bytes) and for those types this field should be set 78 // to NULL. However, for most the data was allocated just for 79 // cross-interpreter use, so it must be freed when 80 // _PyXIData_Release is called or the memory will 81 // leak. In that case, at the very least this field should be set 82 // to PyMem_RawFree (the default if not explicitly set to NULL). 83 // The call will happen with the original interpreter activated. 84 xid_freefunc free; 85 }; 86 87 PyAPI_FUNC(_PyXIData_t *) _PyXIData_New(void); 88 PyAPI_FUNC(void) _PyXIData_Free(_PyXIData_t *data); 89 90 #define _PyXIData_DATA(DATA) ((DATA)->data) 91 #define _PyXIData_OBJ(DATA) ((DATA)->obj) 92 #define _PyXIData_INTERPID(DATA) ((DATA)->interpid) 93 // Users should not need getters for "new_object" or "free". 94 95 96 /* defining cross-interpreter data */ 97 98 PyAPI_FUNC(void) _PyXIData_Init( 99 _PyXIData_t *data, 100 PyInterpreterState *interp, void *shared, PyObject *obj, 101 xid_newobjfunc new_object); 102 PyAPI_FUNC(int) _PyXIData_InitWithSize( 103 _PyXIData_t *, 104 PyInterpreterState *interp, const size_t, PyObject *, 105 xid_newobjfunc); 106 PyAPI_FUNC(void) _PyXIData_Clear(PyInterpreterState *, _PyXIData_t *); 107 108 // Normally the Init* functions are sufficient. The only time 109 // additional initialization might be needed is to set the "free" func, 110 // though that should be infrequent. 111 #define _PyXIData_SET_FREE(DATA, FUNC) \ 112 do { \ 113 (DATA)->free = (FUNC); \ 114 } while (0) 115 #define _PyXIData_CHECK_FREE(DATA, FUNC) \ 116 ((DATA)->free == (FUNC)) 117 // Additionally, some shareable types are essentially light wrappers 118 // around other shareable types. The xidatafunc of the wrapper 119 // can often be implemented by calling the wrapped object's 120 // xidatafunc and then changing the "new_object" function. 121 // We have _PyXIData_SET_NEW_OBJECT() here for that, 122 // but might be better to have a function like 123 // _PyXIData_AdaptToWrapper() instead. 124 #define _PyXIData_SET_NEW_OBJECT(DATA, FUNC) \ 125 do { \ 126 (DATA)->new_object = (FUNC); \ 127 } while (0) 128 #define _PyXIData_CHECK_NEW_OBJECT(DATA, FUNC) \ 129 ((DATA)->new_object == (FUNC)) 130 131 132 /* getting cross-interpreter data */ 133 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; 151 152 PyAPI_FUNC(PyObject *) _PyXIData_GetNotShareableErrorType(PyThreadState *); 153 PyAPI_FUNC(void) _PyXIData_SetNotShareableError(PyThreadState *, const char *); 154 PyAPI_FUNC(void) _PyXIData_FormatNotShareableError( 155 PyThreadState *, 156 const char *, 157 ...); 158 159 PyAPI_FUNC(_PyXIData_getdata_t) _PyXIData_Lookup( 160 PyThreadState *, 161 PyObject *); 162 PyAPI_FUNC(int) _PyObject_CheckXIData( 163 PyThreadState *, 164 PyObject *); 165 166 PyAPI_FUNC(int) _PyObject_GetXIDataNoFallback( 167 PyThreadState *, 168 PyObject *, 169 _PyXIData_t *); 170 PyAPI_FUNC(int) _PyObject_GetXIData( 171 PyThreadState *, 172 PyObject *, 173 xidata_fallback_t, 174 _PyXIData_t *); 175 176 // _PyObject_GetXIData() for bytes 177 typedef struct { 178 const char *bytes; 179 Py_ssize_t len; 180 } _PyBytes_data_t; 181 PyAPI_FUNC(int) _PyBytes_GetData(PyObject *, _PyBytes_data_t *); 182 PyAPI_FUNC(PyObject *) _PyBytes_FromData(_PyBytes_data_t *); 183 PyAPI_FUNC(PyObject *) _PyBytes_FromXIData(_PyXIData_t *); 184 PyAPI_FUNC(int) _PyBytes_GetXIData( 185 PyThreadState *, 186 PyObject *, 187 _PyXIData_t *); 188 PyAPI_FUNC(_PyBytes_data_t *) _PyBytes_GetXIDataWrapped( 189 PyThreadState *, 190 PyObject *, 191 size_t, 192 xid_newobjfunc, 193 _PyXIData_t *); 194 195 // _PyObject_GetXIData() for pickle 196 PyAPI_DATA(PyObject *) _PyPickle_LoadFromXIData(_PyXIData_t *); 197 PyAPI_FUNC(int) _PyPickle_GetXIData( 198 PyThreadState *, 199 PyObject *, 200 _PyXIData_t *); 201 202 // _PyObject_GetXIData() for marshal 203 PyAPI_FUNC(PyObject *) _PyMarshal_ReadObjectFromXIData(_PyXIData_t *); 204 PyAPI_FUNC(int) _PyMarshal_GetXIData( 205 PyThreadState *, 206 PyObject *, 207 _PyXIData_t *); 208 209 // _PyObject_GetXIData() for code objects 210 PyAPI_FUNC(PyObject *) _PyCode_FromXIData(_PyXIData_t *); 211 PyAPI_FUNC(int) _PyCode_GetXIData( 212 PyThreadState *, 213 PyObject *, 214 _PyXIData_t *); 215 PyAPI_FUNC(int) _PyCode_GetScriptXIData( 216 PyThreadState *, 217 PyObject *, 218 _PyXIData_t *); 219 PyAPI_FUNC(int) _PyCode_GetPureScriptXIData( 220 PyThreadState *, 221 PyObject *, 222 _PyXIData_t *); 223 224 // _PyObject_GetXIData() for functions 225 PyAPI_FUNC(PyObject *) _PyFunction_FromXIData(_PyXIData_t *); 226 PyAPI_FUNC(int) _PyFunction_GetXIData( 227 PyThreadState *, 228 PyObject *, 229 _PyXIData_t *); 230 231 232 /* using cross-interpreter data */ 233 234 PyAPI_FUNC(PyObject *) _PyXIData_NewObject(_PyXIData_t *); 235 PyAPI_FUNC(int) _PyXIData_Release(_PyXIData_t *); 236 PyAPI_FUNC(int) _PyXIData_ReleaseAndRawFree(_PyXIData_t *); 237 238 239 /* cross-interpreter data registry */ 240 241 #define Py_CORE_CROSSINTERP_DATA_REGISTRY_H 242 #include "pycore_crossinterp_data_registry.h" 243 #undef Py_CORE_CROSSINTERP_DATA_REGISTRY_H 244 245 246 /*****************************/ 247 /* runtime state & lifecycle */ 248 /*****************************/ 249 250 typedef struct _xid_lookup_state _PyXIData_lookup_t; 251 252 typedef struct { 253 // builtin types 254 _PyXIData_lookup_t data_lookup; 255 } _PyXI_global_state_t; 256 257 typedef struct { 258 // heap types 259 _PyXIData_lookup_t data_lookup; 260 261 struct xi_exceptions { 262 // static types 263 PyObject *PyExc_InterpreterError; 264 PyObject *PyExc_InterpreterNotFoundError; 265 // heap types 266 PyObject *PyExc_NotShareableError; 267 } exceptions; 268 } _PyXI_state_t; 269 270 #define _PyXI_GET_GLOBAL_STATE(interp) (&(interp)->runtime->xi) 271 #define _PyXI_GET_STATE(interp) (&(interp)->xi) 272 273 #ifndef Py_BUILD_CORE_MODULE 274 extern PyStatus _PyXI_Init(PyInterpreterState *interp); 275 extern void _PyXI_Fini(PyInterpreterState *interp); 276 extern PyStatus _PyXI_InitTypes(PyInterpreterState *interp); 277 extern void _PyXI_FiniTypes(PyInterpreterState *interp); 278 #endif // Py_BUILD_CORE_MODULE 279 280 int _Py_xi_global_state_init(_PyXI_global_state_t *); 281 void _Py_xi_global_state_fini(_PyXI_global_state_t *); 282 int _Py_xi_state_init(_PyXI_state_t *, PyInterpreterState *); 283 void _Py_xi_state_fini(_PyXI_state_t *, PyInterpreterState *); 284 285 286 /***************************/ 287 /* short-term data sharing */ 288 /***************************/ 289 290 // Ultimately we'd like to preserve enough information about the 291 // exception and traceback that we could re-constitute (or at least 292 // simulate, a la traceback.TracebackException), and even chain, a copy 293 // of the exception in the calling interpreter. 294 295 typedef struct _excinfo { 296 struct _excinfo_type { 297 PyTypeObject *builtin; 298 const char *name; 299 const char *qualname; 300 const char *module; 301 } type; 302 const char *msg; 303 const char *errdisplay; 304 } _PyXI_excinfo; 305 306 PyAPI_FUNC(_PyXI_excinfo *) _PyXI_NewExcInfo(PyObject *exc); 307 PyAPI_FUNC(void) _PyXI_FreeExcInfo(_PyXI_excinfo *info); 308 PyAPI_FUNC(PyObject *) _PyXI_FormatExcInfo(_PyXI_excinfo *info); 309 PyAPI_FUNC(PyObject *) _PyXI_ExcInfoAsObject(_PyXI_excinfo *info); 310 311 312 typedef enum error_code { 313 _PyXI_ERR_NO_ERROR = 0, 314 _PyXI_ERR_UNCAUGHT_EXCEPTION = -1, 315 _PyXI_ERR_OTHER = -2, 316 _PyXI_ERR_NO_MEMORY = -3, 317 _PyXI_ERR_ALREADY_RUNNING = -4, 318 _PyXI_ERR_MAIN_NS_FAILURE = -5, 319 _PyXI_ERR_APPLY_NS_FAILURE = -6, 320 _PyXI_ERR_PRESERVE_FAILURE = -7, 321 _PyXI_ERR_EXC_PROPAGATION_FAILURE = -8, 322 _PyXI_ERR_NOT_SHAREABLE = -9, 323 } _PyXI_errcode; 324 325 typedef struct xi_failure _PyXI_failure; 326 327 PyAPI_FUNC(_PyXI_failure *) _PyXI_NewFailure(void); 328 PyAPI_FUNC(void) _PyXI_FreeFailure(_PyXI_failure *); 329 PyAPI_FUNC(_PyXI_errcode) _PyXI_GetFailureCode(_PyXI_failure *); 330 PyAPI_FUNC(int) _PyXI_InitFailure(_PyXI_failure *, _PyXI_errcode, PyObject *); 331 PyAPI_FUNC(void) _PyXI_InitFailureUTF8( 332 _PyXI_failure *, 333 _PyXI_errcode, 334 const char *); 335 336 PyAPI_FUNC(int) _PyXI_UnwrapNotShareableError( 337 PyThreadState *, 338 _PyXI_failure *); 339 340 341 // A cross-interpreter session involves entering an interpreter 342 // with _PyXI_Enter(), doing some work with it, and finally exiting 343 // that interpreter with _PyXI_Exit(). 344 // 345 // At the boundaries of the session, both entering and exiting, 346 // data may be exchanged between the previous interpreter and the 347 // target one in a thread-safe way that does not violate the 348 // isolation between interpreters. This includes setting objects 349 // in the target's __main__ module on the way in, and capturing 350 // uncaught exceptions on the way out. 351 typedef struct xi_session _PyXI_session; 352 353 PyAPI_FUNC(_PyXI_session *) _PyXI_NewSession(void); 354 PyAPI_FUNC(void) _PyXI_FreeSession(_PyXI_session *); 355 356 typedef struct { 357 PyObject *preserved; 358 PyObject *excinfo; 359 _PyXI_errcode errcode; 360 } _PyXI_session_result; 361 PyAPI_FUNC(void) _PyXI_ClearResult(_PyXI_session_result *); 362 363 PyAPI_FUNC(int) _PyXI_Enter( 364 _PyXI_session *session, 365 PyInterpreterState *interp, 366 PyObject *nsupdates, 367 _PyXI_session_result *); 368 PyAPI_FUNC(int) _PyXI_Exit( 369 _PyXI_session *, 370 _PyXI_failure *, 371 _PyXI_session_result *); 372 373 PyAPI_FUNC(PyObject *) _PyXI_GetMainNamespace( 374 _PyXI_session *, 375 _PyXI_failure *); 376 377 PyAPI_FUNC(int) _PyXI_Preserve( 378 _PyXI_session *, 379 const char *, 380 PyObject *, 381 _PyXI_failure *); 382 PyAPI_FUNC(PyObject *) _PyXI_GetPreserved( 383 _PyXI_session_result *, 384 const char *); 385 386 387 /*************/ 388 /* other API */ 389 /*************/ 390 391 // Export for _testinternalcapi shared extension 392 PyAPI_FUNC(PyInterpreterState *) _PyXI_NewInterpreter( 393 PyInterpreterConfig *config, 394 long *maybe_whence, 395 PyThreadState **p_tstate, 396 PyThreadState **p_save_tstate); 397 PyAPI_FUNC(void) _PyXI_EndInterpreter( 398 PyInterpreterState *interp, 399 PyThreadState *tstate, 400 PyThreadState **p_save_tstate); 401 402 403 #ifdef __cplusplus 404 } 405 #endif 406 #endif /* !Py_INTERNAL_CROSSINTERP_H */