• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* interpreters module */
2 /* low-level access to interpreter primitives */
3 
4 #ifndef Py_BUILD_CORE_BUILTIN
5 #  define Py_BUILD_CORE_MODULE 1
6 #endif
7 
8 #include "Python.h"
9 #include "pycore_abstract.h"      // _PyIndex_Check()
10 #include "pycore_crossinterp.h"   // struct _xid
11 #include "pycore_interp.h"        // _PyInterpreterState_IDIncref()
12 #include "pycore_initconfig.h"    // _PyErr_SetFromPyStatus()
13 #include "pycore_long.h"          // _PyLong_IsNegative()
14 #include "pycore_modsupport.h"    // _PyArg_BadArgument()
15 #include "pycore_namespace.h"     // _PyNamespace_New()
16 #include "pycore_pybuffer.h"      // _PyBuffer_ReleaseInInterpreterAndRawFree()
17 #include "pycore_pyerrors.h"      // _Py_excinfo
18 #include "pycore_pylifecycle.h"   // _PyInterpreterConfig_AsDict()
19 #include "pycore_pystate.h"       // _PyInterpreterState_SetRunningMain()
20 
21 #include "marshal.h"              // PyMarshal_ReadObjectFromString()
22 
23 #include "_interpreters_common.h"
24 
25 
26 #define MODULE_NAME _interpreters
27 #define MODULE_NAME_STR Py_STRINGIFY(MODULE_NAME)
28 #define MODINIT_FUNC_NAME RESOLVE_MODINIT_FUNC_NAME(MODULE_NAME)
29 
30 
31 static PyInterpreterState *
_get_current_interp(void)32 _get_current_interp(void)
33 {
34     // PyInterpreterState_Get() aborts if lookup fails, so don't need
35     // to check the result for NULL.
36     return PyInterpreterState_Get();
37 }
38 
39 #define look_up_interp _PyInterpreterState_LookUpIDObject
40 
41 
42 static PyObject *
_get_current_module(void)43 _get_current_module(void)
44 {
45     PyObject *name = PyUnicode_FromString(MODULE_NAME_STR);
46     if (name == NULL) {
47         return NULL;
48     }
49     PyObject *mod = PyImport_GetModule(name);
50     Py_DECREF(name);
51     if (mod == NULL) {
52         return NULL;
53     }
54     assert(mod != Py_None);
55     return mod;
56 }
57 
58 
59 static int
is_running_main(PyInterpreterState * interp)60 is_running_main(PyInterpreterState *interp)
61 {
62     if (_PyInterpreterState_IsRunningMain(interp)) {
63         return 1;
64     }
65     // Unlike with the general C-API, we can be confident that someone
66     // using this module for the main interpreter is doing so through
67     // the main program.  Thus we can make this extra check.  This benefits
68     // applications that embed Python but haven't been updated yet
69     // to call_PyInterpreterState_SetRunningMain().
70     if (_Py_IsMainInterpreter(interp)) {
71         return 1;
72     }
73     return 0;
74 }
75 
76 
77 /* Cross-interpreter Buffer Views *******************************************/
78 
79 // XXX Release when the original interpreter is destroyed.
80 
81 typedef struct {
82     PyObject_HEAD
83     Py_buffer *view;
84     int64_t interpid;
85 } XIBufferViewObject;
86 
87 static PyObject *
xibufferview_from_xid(PyTypeObject * cls,_PyCrossInterpreterData * data)88 xibufferview_from_xid(PyTypeObject *cls, _PyCrossInterpreterData *data)
89 {
90     assert(_PyCrossInterpreterData_DATA(data) != NULL);
91     assert(_PyCrossInterpreterData_OBJ(data) == NULL);
92     assert(_PyCrossInterpreterData_INTERPID(data) >= 0);
93     XIBufferViewObject *self = PyObject_Malloc(sizeof(XIBufferViewObject));
94     if (self == NULL) {
95         return NULL;
96     }
97     PyObject_Init((PyObject *)self, cls);
98     self->view = (Py_buffer *)_PyCrossInterpreterData_DATA(data);
99     self->interpid = _PyCrossInterpreterData_INTERPID(data);
100     return (PyObject *)self;
101 }
102 
103 static void
xibufferview_dealloc(XIBufferViewObject * self)104 xibufferview_dealloc(XIBufferViewObject *self)
105 {
106     PyInterpreterState *interp = _PyInterpreterState_LookUpID(self->interpid);
107     /* If the interpreter is no longer alive then we have problems,
108        since other objects may be using the buffer still. */
109     assert(interp != NULL);
110 
111     if (_PyBuffer_ReleaseInInterpreterAndRawFree(interp, self->view) < 0) {
112         // XXX Emit a warning?
113         PyErr_Clear();
114     }
115 
116     PyTypeObject *tp = Py_TYPE(self);
117     tp->tp_free(self);
118     /* "Instances of heap-allocated types hold a reference to their type."
119      * See: https://docs.python.org/3.11/howto/isolating-extensions.html#garbage-collection-protocol
120      * See: https://docs.python.org/3.11/c-api/typeobj.html#c.PyTypeObject.tp_traverse
121     */
122     // XXX Why don't we implement Py_TPFLAGS_HAVE_GC, e.g. Py_tp_traverse,
123     // like we do for _abc._abc_data?
124     Py_DECREF(tp);
125 }
126 
127 static int
xibufferview_getbuf(XIBufferViewObject * self,Py_buffer * view,int flags)128 xibufferview_getbuf(XIBufferViewObject *self, Py_buffer *view, int flags)
129 {
130     /* Only PyMemoryView_FromObject() should ever call this,
131        via _memoryview_from_xid() below. */
132     *view = *self->view;
133     view->obj = (PyObject *)self;
134     // XXX Should we leave it alone?
135     view->internal = NULL;
136     return 0;
137 }
138 
139 static PyType_Slot XIBufferViewType_slots[] = {
140     {Py_tp_dealloc, (destructor)xibufferview_dealloc},
141     {Py_bf_getbuffer, (getbufferproc)xibufferview_getbuf},
142     // We don't bother with Py_bf_releasebuffer since we don't need it.
143     {0, NULL},
144 };
145 
146 static PyType_Spec XIBufferViewType_spec = {
147     .name = MODULE_NAME_STR ".CrossInterpreterBufferView",
148     .basicsize = sizeof(XIBufferViewObject),
149     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
150               Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE),
151     .slots = XIBufferViewType_slots,
152 };
153 
154 
155 static PyTypeObject * _get_current_xibufferview_type(void);
156 
157 static PyObject *
_memoryview_from_xid(_PyCrossInterpreterData * data)158 _memoryview_from_xid(_PyCrossInterpreterData *data)
159 {
160     PyTypeObject *cls = _get_current_xibufferview_type();
161     if (cls == NULL) {
162         return NULL;
163     }
164     PyObject *obj = xibufferview_from_xid(cls, data);
165     if (obj == NULL) {
166         return NULL;
167     }
168     return PyMemoryView_FromObject(obj);
169 }
170 
171 static int
_memoryview_shared(PyThreadState * tstate,PyObject * obj,_PyCrossInterpreterData * data)172 _memoryview_shared(PyThreadState *tstate, PyObject *obj,
173                    _PyCrossInterpreterData *data)
174 {
175     Py_buffer *view = PyMem_RawMalloc(sizeof(Py_buffer));
176     if (view == NULL) {
177         return -1;
178     }
179     if (PyObject_GetBuffer(obj, view, PyBUF_FULL_RO) < 0) {
180         PyMem_RawFree(view);
181         return -1;
182     }
183     _PyCrossInterpreterData_Init(data, tstate->interp, view, NULL,
184                                  _memoryview_from_xid);
185     return 0;
186 }
187 
188 static int
register_memoryview_xid(PyObject * mod,PyTypeObject ** p_state)189 register_memoryview_xid(PyObject *mod, PyTypeObject **p_state)
190 {
191     // XIBufferView
192     assert(*p_state == NULL);
193     PyTypeObject *cls = (PyTypeObject *)PyType_FromModuleAndSpec(
194                 mod, &XIBufferViewType_spec, NULL);
195     if (cls == NULL) {
196         return -1;
197     }
198     if (PyModule_AddType(mod, cls) < 0) {
199         Py_DECREF(cls);
200         return -1;
201     }
202     *p_state = cls;
203 
204     // Register XID for the builtin memoryview type.
205     if (ensure_xid_class(&PyMemoryView_Type, _memoryview_shared) < 0) {
206         return -1;
207     }
208     // We don't ever bother un-registering memoryview.
209 
210     return 0;
211 }
212 
213 
214 
215 /* module state *************************************************************/
216 
217 typedef struct {
218     int _notused;
219 
220     /* heap types */
221     PyTypeObject *XIBufferViewType;
222 } module_state;
223 
224 static inline module_state *
get_module_state(PyObject * mod)225 get_module_state(PyObject *mod)
226 {
227     assert(mod != NULL);
228     module_state *state = PyModule_GetState(mod);
229     assert(state != NULL);
230     return state;
231 }
232 
233 static module_state *
_get_current_module_state(void)234 _get_current_module_state(void)
235 {
236     PyObject *mod = _get_current_module();
237     if (mod == NULL) {
238         // XXX import it?
239         PyErr_SetString(PyExc_RuntimeError,
240                         MODULE_NAME_STR " module not imported yet");
241         return NULL;
242     }
243     module_state *state = get_module_state(mod);
244     Py_DECREF(mod);
245     return state;
246 }
247 
248 static int
traverse_module_state(module_state * state,visitproc visit,void * arg)249 traverse_module_state(module_state *state, visitproc visit, void *arg)
250 {
251     /* heap types */
252     Py_VISIT(state->XIBufferViewType);
253 
254     return 0;
255 }
256 
257 static int
clear_module_state(module_state * state)258 clear_module_state(module_state *state)
259 {
260     /* heap types */
261     Py_CLEAR(state->XIBufferViewType);
262 
263     return 0;
264 }
265 
266 
267 static PyTypeObject *
_get_current_xibufferview_type(void)268 _get_current_xibufferview_type(void)
269 {
270     module_state *state = _get_current_module_state();
271     if (state == NULL) {
272         return NULL;
273     }
274     return state->XIBufferViewType;
275 }
276 
277 
278 /* Python code **************************************************************/
279 
280 static const char *
check_code_str(PyUnicodeObject * text)281 check_code_str(PyUnicodeObject *text)
282 {
283     assert(text != NULL);
284     if (PyUnicode_GET_LENGTH(text) == 0) {
285         return "too short";
286     }
287 
288     // XXX Verify that it parses?
289 
290     return NULL;
291 }
292 
293 static const char *
check_code_object(PyCodeObject * code)294 check_code_object(PyCodeObject *code)
295 {
296     assert(code != NULL);
297     if (code->co_argcount > 0
298         || code->co_posonlyargcount > 0
299         || code->co_kwonlyargcount > 0
300         || code->co_flags & (CO_VARARGS | CO_VARKEYWORDS))
301     {
302         return "arguments not supported";
303     }
304     if (code->co_ncellvars > 0) {
305         return "closures not supported";
306     }
307     // We trust that no code objects under co_consts have unbound cell vars.
308 
309     if (_PyCode_HAS_EXECUTORS(code) || _PyCode_HAS_INSTRUMENTATION(code)) {
310         return "only basic functions are supported";
311     }
312     if (code->_co_monitoring != NULL) {
313         return "only basic functions are supported";
314     }
315     if (code->co_extra != NULL) {
316         return "only basic functions are supported";
317     }
318 
319     return NULL;
320 }
321 
322 #define RUN_TEXT 1
323 #define RUN_CODE 2
324 
325 static const char *
get_code_str(PyObject * arg,Py_ssize_t * len_p,PyObject ** bytes_p,int * flags_p)326 get_code_str(PyObject *arg, Py_ssize_t *len_p, PyObject **bytes_p, int *flags_p)
327 {
328     const char *codestr = NULL;
329     Py_ssize_t len = -1;
330     PyObject *bytes_obj = NULL;
331     int flags = 0;
332 
333     if (PyUnicode_Check(arg)) {
334         assert(PyUnicode_CheckExact(arg)
335                && (check_code_str((PyUnicodeObject *)arg) == NULL));
336         codestr = PyUnicode_AsUTF8AndSize(arg, &len);
337         if (codestr == NULL) {
338             return NULL;
339         }
340         if (strlen(codestr) != (size_t)len) {
341             PyErr_SetString(PyExc_ValueError,
342                             "source code string cannot contain null bytes");
343             return NULL;
344         }
345         flags = RUN_TEXT;
346     }
347     else {
348         assert(PyCode_Check(arg)
349                && (check_code_object((PyCodeObject *)arg) == NULL));
350         flags = RUN_CODE;
351 
352         // Serialize the code object.
353         bytes_obj = PyMarshal_WriteObjectToString(arg, Py_MARSHAL_VERSION);
354         if (bytes_obj == NULL) {
355             return NULL;
356         }
357         codestr = PyBytes_AS_STRING(bytes_obj);
358         len = PyBytes_GET_SIZE(bytes_obj);
359     }
360 
361     *flags_p = flags;
362     *bytes_p = bytes_obj;
363     *len_p = len;
364     return codestr;
365 }
366 
367 
368 /* interpreter-specific code ************************************************/
369 
370 static int
init_named_config(PyInterpreterConfig * config,const char * name)371 init_named_config(PyInterpreterConfig *config, const char *name)
372 {
373     if (name == NULL
374             || strcmp(name, "") == 0
375             || strcmp(name, "default") == 0)
376     {
377         name = "isolated";
378     }
379 
380     if (strcmp(name, "isolated") == 0) {
381         *config = (PyInterpreterConfig)_PyInterpreterConfig_INIT;
382     }
383     else if (strcmp(name, "legacy") == 0) {
384         *config = (PyInterpreterConfig)_PyInterpreterConfig_LEGACY_INIT;
385     }
386     else if (strcmp(name, "empty") == 0) {
387         *config = (PyInterpreterConfig){0};
388     }
389     else {
390         PyErr_Format(PyExc_ValueError,
391                      "unsupported config name '%s'", name);
392         return -1;
393     }
394     return 0;
395 }
396 
397 static int
config_from_object(PyObject * configobj,PyInterpreterConfig * config)398 config_from_object(PyObject *configobj, PyInterpreterConfig *config)
399 {
400     if (configobj == NULL || configobj == Py_None) {
401         if (init_named_config(config, NULL) < 0) {
402             return -1;
403         }
404     }
405     else if (PyUnicode_Check(configobj)) {
406         const char *utf8name = PyUnicode_AsUTF8(configobj);
407         if (utf8name == NULL) {
408             return -1;
409         }
410         if (init_named_config(config, utf8name) < 0) {
411             return -1;
412         }
413     }
414     else {
415         PyObject *dict = PyObject_GetAttrString(configobj, "__dict__");
416         if (dict == NULL) {
417             PyErr_Format(PyExc_TypeError, "bad config %R", configobj);
418             return -1;
419         }
420         int res = _PyInterpreterConfig_InitFromDict(config, dict);
421         Py_DECREF(dict);
422         if (res < 0) {
423             return -1;
424         }
425     }
426     return 0;
427 }
428 
429 
430 static int
_run_script(PyObject * ns,const char * codestr,Py_ssize_t codestrlen,int flags)431 _run_script(PyObject *ns, const char *codestr, Py_ssize_t codestrlen, int flags)
432 {
433     PyObject *result = NULL;
434     if (flags & RUN_TEXT) {
435         result = PyRun_StringFlags(codestr, Py_file_input, ns, ns, NULL);
436     }
437     else if (flags & RUN_CODE) {
438         PyObject *code = PyMarshal_ReadObjectFromString(codestr, codestrlen);
439         if (code != NULL) {
440             result = PyEval_EvalCode(code, ns, ns);
441             Py_DECREF(code);
442         }
443     }
444     else {
445         Py_UNREACHABLE();
446     }
447     if (result == NULL) {
448         return -1;
449     }
450     Py_DECREF(result);  // We throw away the result.
451     return 0;
452 }
453 
454 static int
_run_in_interpreter(PyInterpreterState * interp,const char * codestr,Py_ssize_t codestrlen,PyObject * shareables,int flags,PyObject ** p_excinfo)455 _run_in_interpreter(PyInterpreterState *interp,
456                     const char *codestr, Py_ssize_t codestrlen,
457                     PyObject *shareables, int flags,
458                     PyObject **p_excinfo)
459 {
460     assert(!PyErr_Occurred());
461     _PyXI_session session = {0};
462 
463     // Prep and switch interpreters.
464     if (_PyXI_Enter(&session, interp, shareables) < 0) {
465         assert(!PyErr_Occurred());
466         PyObject *excinfo = _PyXI_ApplyError(session.error);
467         if (excinfo != NULL) {
468             *p_excinfo = excinfo;
469         }
470         assert(PyErr_Occurred());
471         return -1;
472     }
473 
474     // Run the script.
475     int res = _run_script(session.main_ns, codestr, codestrlen, flags);
476 
477     // Clean up and switch back.
478     _PyXI_Exit(&session);
479 
480     // Propagate any exception out to the caller.
481     assert(!PyErr_Occurred());
482     if (res < 0) {
483         PyObject *excinfo = _PyXI_ApplyCapturedException(&session);
484         if (excinfo != NULL) {
485             *p_excinfo = excinfo;
486         }
487     }
488     else {
489         assert(!_PyXI_HasCapturedException(&session));
490     }
491 
492     return res;
493 }
494 
495 
496 /* module level code ********************************************************/
497 
498 static long
get_whence(PyInterpreterState * interp)499 get_whence(PyInterpreterState *interp)
500 {
501     return _PyInterpreterState_GetWhence(interp);
502 }
503 
504 
505 static PyInterpreterState *
resolve_interp(PyObject * idobj,int restricted,int reqready,const char * op)506 resolve_interp(PyObject *idobj, int restricted, int reqready, const char *op)
507 {
508     PyInterpreterState *interp;
509     if (idobj == NULL) {
510         interp = PyInterpreterState_Get();
511     }
512     else {
513         interp = look_up_interp(idobj);
514         if (interp == NULL) {
515             return NULL;
516         }
517     }
518 
519     if (reqready && !_PyInterpreterState_IsReady(interp)) {
520         if (idobj == NULL) {
521             PyErr_Format(PyExc_InterpreterError,
522                          "cannot %s current interpreter (not ready)", op);
523         }
524         else {
525             PyErr_Format(PyExc_InterpreterError,
526                          "cannot %s interpreter %R (not ready)", op, idobj);
527         }
528         return NULL;
529     }
530 
531     if (restricted && get_whence(interp) != _PyInterpreterState_WHENCE_STDLIB) {
532         if (idobj == NULL) {
533             PyErr_Format(PyExc_InterpreterError,
534                          "cannot %s unrecognized current interpreter", op);
535         }
536         else {
537             PyErr_Format(PyExc_InterpreterError,
538                          "cannot %s unrecognized interpreter %R", op, idobj);
539         }
540         return NULL;
541     }
542 
543     return interp;
544 }
545 
546 
547 static PyObject *
get_summary(PyInterpreterState * interp)548 get_summary(PyInterpreterState *interp)
549 {
550     PyObject *idobj = _PyInterpreterState_GetIDObject(interp);
551     if (idobj == NULL) {
552         return NULL;
553     }
554     PyObject *whenceobj = PyLong_FromLong(
555                             get_whence(interp));
556     if (whenceobj == NULL) {
557         Py_DECREF(idobj);
558         return NULL;
559     }
560     PyObject *res = PyTuple_Pack(2, idobj, whenceobj);
561     Py_DECREF(idobj);
562     Py_DECREF(whenceobj);
563     return res;
564 }
565 
566 
567 static PyObject *
interp_new_config(PyObject * self,PyObject * args,PyObject * kwds)568 interp_new_config(PyObject *self, PyObject *args, PyObject *kwds)
569 {
570     const char *name = NULL;
571     if (!PyArg_ParseTuple(args, "|s:" MODULE_NAME_STR ".new_config",
572                           &name))
573     {
574         return NULL;
575     }
576     PyObject *overrides = kwds;
577 
578     PyInterpreterConfig config;
579     if (init_named_config(&config, name) < 0) {
580         return NULL;
581     }
582 
583     if (overrides != NULL && PyDict_GET_SIZE(overrides) > 0) {
584         if (_PyInterpreterConfig_UpdateFromDict(&config, overrides) < 0) {
585             return NULL;
586         }
587     }
588 
589     PyObject *dict = _PyInterpreterConfig_AsDict(&config);
590     if (dict == NULL) {
591         return NULL;
592     }
593 
594     PyObject *configobj = _PyNamespace_New(dict);
595     Py_DECREF(dict);
596     return configobj;
597 }
598 
599 PyDoc_STRVAR(new_config_doc,
600 "new_config(name='isolated', /, **overrides) -> type.SimpleNamespace\n\
601 \n\
602 Return a representation of a new PyInterpreterConfig.\n\
603 \n\
604 The name determines the initial values of the config.  Supported named\n\
605 configs are: default, isolated, legacy, and empty.\n\
606 \n\
607 Any keyword arguments are set on the corresponding config fields,\n\
608 overriding the initial values.");
609 
610 
611 static PyObject *
interp_create(PyObject * self,PyObject * args,PyObject * kwds)612 interp_create(PyObject *self, PyObject *args, PyObject *kwds)
613 {
614     static char *kwlist[] = {"config", "reqrefs", NULL};
615     PyObject *configobj = NULL;
616     int reqrefs = 0;
617     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O$p:create", kwlist,
618                                      &configobj, &reqrefs)) {
619         return NULL;
620     }
621 
622     PyInterpreterConfig config;
623     if (config_from_object(configobj, &config) < 0) {
624         return NULL;
625     }
626 
627     long whence = _PyInterpreterState_WHENCE_STDLIB;
628     PyInterpreterState *interp = \
629             _PyXI_NewInterpreter(&config, &whence, NULL, NULL);
630     if (interp == NULL) {
631         // XXX Move the chained exception to interpreters.create()?
632         PyObject *exc = PyErr_GetRaisedException();
633         assert(exc != NULL);
634         PyErr_SetString(PyExc_InterpreterError, "interpreter creation failed");
635         _PyErr_ChainExceptions1(exc);
636         return NULL;
637     }
638     assert(_PyInterpreterState_IsReady(interp));
639 
640     PyObject *idobj = _PyInterpreterState_GetIDObject(interp);
641     if (idobj == NULL) {
642         _PyXI_EndInterpreter(interp, NULL, NULL);
643         return NULL;
644     }
645 
646     if (reqrefs) {
647         // Decref to 0 will destroy the interpreter.
648         _PyInterpreterState_RequireIDRef(interp, 1);
649     }
650 
651     return idobj;
652 }
653 
654 
655 PyDoc_STRVAR(create_doc,
656 "create([config], *, reqrefs=False) -> ID\n\
657 \n\
658 Create a new interpreter and return a unique generated ID.\n\
659 \n\
660 The caller is responsible for destroying the interpreter before exiting,\n\
661 typically by using _interpreters.destroy().  This can be managed \n\
662 automatically by passing \"reqrefs=True\" and then using _incref() and\n\
663 _decref()` appropriately.\n\
664 \n\
665 \"config\" must be a valid interpreter config or the name of a\n\
666 predefined config (\"isolated\" or \"legacy\").  The default\n\
667 is \"isolated\".");
668 
669 
670 static PyObject *
interp_destroy(PyObject * self,PyObject * args,PyObject * kwds)671 interp_destroy(PyObject *self, PyObject *args, PyObject *kwds)
672 {
673     static char *kwlist[] = {"id", "restrict", NULL};
674     PyObject *id;
675     int restricted = 0;
676     // XXX Use "L" for id?
677     if (!PyArg_ParseTupleAndKeywords(args, kwds,
678                                      "O|$p:destroy", kwlist, &id, &restricted))
679     {
680         return NULL;
681     }
682 
683     // Look up the interpreter.
684     int reqready = 0;
685     PyInterpreterState *interp = \
686             resolve_interp(id, restricted, reqready, "destroy");
687     if (interp == NULL) {
688         return NULL;
689     }
690 
691     // Ensure we don't try to destroy the current interpreter.
692     PyInterpreterState *current = _get_current_interp();
693     if (current == NULL) {
694         return NULL;
695     }
696     if (interp == current) {
697         PyErr_SetString(PyExc_InterpreterError,
698                         "cannot destroy the current interpreter");
699         return NULL;
700     }
701 
702     // Ensure the interpreter isn't running.
703     /* XXX We *could* support destroying a running interpreter but
704        aren't going to worry about it for now. */
705     if (is_running_main(interp)) {
706         PyErr_Format(PyExc_InterpreterError, "interpreter running");
707         return NULL;
708     }
709 
710     // Destroy the interpreter.
711     _PyXI_EndInterpreter(interp, NULL, NULL);
712 
713     Py_RETURN_NONE;
714 }
715 
716 PyDoc_STRVAR(destroy_doc,
717 "destroy(id, *, restrict=False)\n\
718 \n\
719 Destroy the identified interpreter.\n\
720 \n\
721 Attempting to destroy the current interpreter raises InterpreterError.\n\
722 So does an unrecognized ID.");
723 
724 
725 static PyObject *
interp_list_all(PyObject * self,PyObject * args,PyObject * kwargs)726 interp_list_all(PyObject *self, PyObject *args, PyObject *kwargs)
727 {
728     static char *kwlist[] = {"require_ready", NULL};
729     int reqready = 0;
730     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
731                                      "|$p:" MODULE_NAME_STR ".list_all",
732                                      kwlist, &reqready))
733     {
734         return NULL;
735     }
736 
737     PyObject *ids = PyList_New(0);
738     if (ids == NULL) {
739         return NULL;
740     }
741 
742     PyInterpreterState *interp = PyInterpreterState_Head();
743     while (interp != NULL) {
744         if (!reqready || _PyInterpreterState_IsReady(interp)) {
745             PyObject *item = get_summary(interp);
746             if (item == NULL) {
747                 Py_DECREF(ids);
748                 return NULL;
749             }
750 
751             // insert at front of list
752             int res = PyList_Insert(ids, 0, item);
753             Py_DECREF(item);
754             if (res < 0) {
755                 Py_DECREF(ids);
756                 return NULL;
757             }
758         }
759         interp = PyInterpreterState_Next(interp);
760     }
761 
762     return ids;
763 }
764 
765 PyDoc_STRVAR(list_all_doc,
766 "list_all() -> [(ID, whence)]\n\
767 \n\
768 Return a list containing the ID of every existing interpreter.");
769 
770 
771 static PyObject *
interp_get_current(PyObject * self,PyObject * Py_UNUSED (ignored))772 interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored))
773 {
774     PyInterpreterState *interp =_get_current_interp();
775     if (interp == NULL) {
776         return NULL;
777     }
778     assert(_PyInterpreterState_IsReady(interp));
779     return get_summary(interp);
780 }
781 
782 PyDoc_STRVAR(get_current_doc,
783 "get_current() -> (ID, whence)\n\
784 \n\
785 Return the ID of current interpreter.");
786 
787 
788 static PyObject *
interp_get_main(PyObject * self,PyObject * Py_UNUSED (ignored))789 interp_get_main(PyObject *self, PyObject *Py_UNUSED(ignored))
790 {
791     PyInterpreterState *interp = _PyInterpreterState_Main();
792     assert(_PyInterpreterState_IsReady(interp));
793     return get_summary(interp);
794 }
795 
796 PyDoc_STRVAR(get_main_doc,
797 "get_main() -> (ID, whence)\n\
798 \n\
799 Return the ID of main interpreter.");
800 
801 
802 static PyObject *
interp_set___main___attrs(PyObject * self,PyObject * args,PyObject * kwargs)803 interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
804 {
805     static char *kwlist[] = {"id", "updates", "restrict", NULL};
806     PyObject *id, *updates;
807     int restricted = 0;
808     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
809                                      "OO|$p:" MODULE_NAME_STR ".set___main___attrs",
810                                      kwlist, &id, &updates, &restricted))
811     {
812         return NULL;
813     }
814 
815     // Look up the interpreter.
816     int reqready = 1;
817     PyInterpreterState *interp = \
818             resolve_interp(id, restricted, reqready, "update __main__ for");
819     if (interp == NULL) {
820         return NULL;
821     }
822 
823     // Check the updates.
824     if (updates != Py_None) {
825         Py_ssize_t size = PyObject_Size(updates);
826         if (size < 0) {
827             return NULL;
828         }
829         if (size == 0) {
830             PyErr_SetString(PyExc_ValueError,
831                             "arg 2 must be a non-empty mapping");
832             return NULL;
833         }
834     }
835 
836     _PyXI_session session = {0};
837 
838     // Prep and switch interpreters, including apply the updates.
839     if (_PyXI_Enter(&session, interp, updates) < 0) {
840         if (!PyErr_Occurred()) {
841             _PyXI_ApplyCapturedException(&session);
842             assert(PyErr_Occurred());
843         }
844         else {
845             assert(!_PyXI_HasCapturedException(&session));
846         }
847         return NULL;
848     }
849 
850     // Clean up and switch back.
851     _PyXI_Exit(&session);
852 
853     Py_RETURN_NONE;
854 }
855 
856 PyDoc_STRVAR(set___main___attrs_doc,
857 "set___main___attrs(id, ns, *, restrict=False)\n\
858 \n\
859 Bind the given attributes in the interpreter's __main__ module.");
860 
861 
862 static PyUnicodeObject *
convert_script_arg(PyObject * arg,const char * fname,const char * displayname,const char * expected)863 convert_script_arg(PyObject *arg, const char *fname, const char *displayname,
864                    const char *expected)
865 {
866     PyUnicodeObject *str = NULL;
867     if (PyUnicode_CheckExact(arg)) {
868         str = (PyUnicodeObject *)Py_NewRef(arg);
869     }
870     else if (PyUnicode_Check(arg)) {
871         // XXX str = PyUnicode_FromObject(arg);
872         str = (PyUnicodeObject *)Py_NewRef(arg);
873     }
874     else {
875         _PyArg_BadArgument(fname, displayname, expected, arg);
876         return NULL;
877     }
878 
879     const char *err = check_code_str(str);
880     if (err != NULL) {
881         Py_DECREF(str);
882         PyErr_Format(PyExc_ValueError,
883                      "%.200s(): bad script text (%s)", fname, err);
884         return NULL;
885     }
886 
887     return str;
888 }
889 
890 static PyCodeObject *
convert_code_arg(PyObject * arg,const char * fname,const char * displayname,const char * expected)891 convert_code_arg(PyObject *arg, const char *fname, const char *displayname,
892                  const char *expected)
893 {
894     const char *kind = NULL;
895     PyCodeObject *code = NULL;
896     if (PyFunction_Check(arg)) {
897         if (PyFunction_GetClosure(arg) != NULL) {
898             PyErr_Format(PyExc_ValueError,
899                          "%.200s(): closures not supported", fname);
900             return NULL;
901         }
902         code = (PyCodeObject *)PyFunction_GetCode(arg);
903         if (code == NULL) {
904             if (PyErr_Occurred()) {
905                 // This chains.
906                 PyErr_Format(PyExc_ValueError,
907                              "%.200s(): bad func", fname);
908             }
909             else {
910                 PyErr_Format(PyExc_ValueError,
911                              "%.200s(): func.__code__ missing", fname);
912             }
913             return NULL;
914         }
915         Py_INCREF(code);
916         kind = "func";
917     }
918     else if (PyCode_Check(arg)) {
919         code = (PyCodeObject *)Py_NewRef(arg);
920         kind = "code object";
921     }
922     else {
923         _PyArg_BadArgument(fname, displayname, expected, arg);
924         return NULL;
925     }
926 
927     const char *err = check_code_object(code);
928     if (err != NULL) {
929         Py_DECREF(code);
930         PyErr_Format(PyExc_ValueError,
931                      "%.200s(): bad %s (%s)", fname, kind, err);
932         return NULL;
933     }
934 
935     return code;
936 }
937 
938 static int
_interp_exec(PyObject * self,PyInterpreterState * interp,PyObject * code_arg,PyObject * shared_arg,PyObject ** p_excinfo)939 _interp_exec(PyObject *self, PyInterpreterState *interp,
940              PyObject *code_arg, PyObject *shared_arg, PyObject **p_excinfo)
941 {
942     if (shared_arg != NULL && !PyDict_CheckExact(shared_arg)) {
943         PyErr_SetString(PyExc_TypeError, "expected 'shared' to be a dict");
944         return -1;
945     }
946 
947     // Extract code.
948     Py_ssize_t codestrlen = -1;
949     PyObject *bytes_obj = NULL;
950     int flags = 0;
951     const char *codestr = get_code_str(code_arg,
952                                        &codestrlen, &bytes_obj, &flags);
953     if (codestr == NULL) {
954         return -1;
955     }
956 
957     // Run the code in the interpreter.
958     int res = _run_in_interpreter(interp, codestr, codestrlen,
959                                   shared_arg, flags, p_excinfo);
960     Py_XDECREF(bytes_obj);
961     if (res < 0) {
962         return -1;
963     }
964 
965     return 0;
966 }
967 
968 static PyObject *
interp_exec(PyObject * self,PyObject * args,PyObject * kwds)969 interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
970 {
971     static char *kwlist[] = {"id", "code", "shared", "restrict", NULL};
972     PyObject *id, *code;
973     PyObject *shared = NULL;
974     int restricted = 0;
975     if (!PyArg_ParseTupleAndKeywords(args, kwds,
976                                      "OO|O$p:" MODULE_NAME_STR ".exec", kwlist,
977                                      &id, &code, &shared, &restricted))
978     {
979         return NULL;
980     }
981 
982     int reqready = 1;
983     PyInterpreterState *interp = \
984             resolve_interp(id, restricted, reqready, "exec code for");
985     if (interp == NULL) {
986         return NULL;
987     }
988 
989     const char *expected = "a string, a function, or a code object";
990     if (PyUnicode_Check(code)) {
991          code = (PyObject *)convert_script_arg(code, MODULE_NAME_STR ".exec",
992                                                "argument 2", expected);
993     }
994     else {
995          code = (PyObject *)convert_code_arg(code, MODULE_NAME_STR ".exec",
996                                              "argument 2", expected);
997     }
998     if (code == NULL) {
999         return NULL;
1000     }
1001 
1002     PyObject *excinfo = NULL;
1003     int res = _interp_exec(self, interp, code, shared, &excinfo);
1004     Py_DECREF(code);
1005     if (res < 0) {
1006         assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
1007         return excinfo;
1008     }
1009     Py_RETURN_NONE;
1010 }
1011 
1012 PyDoc_STRVAR(exec_doc,
1013 "exec(id, code, shared=None, *, restrict=False)\n\
1014 \n\
1015 Execute the provided code in the identified interpreter.\n\
1016 This is equivalent to running the builtin exec() under the target\n\
1017 interpreter, using the __dict__ of its __main__ module as both\n\
1018 globals and locals.\n\
1019 \n\
1020 \"code\" may be a string containing the text of a Python script.\n\
1021 \n\
1022 Functions (and code objects) are also supported, with some restrictions.\n\
1023 The code/function must not take any arguments or be a closure\n\
1024 (i.e. have cell vars).  Methods and other callables are not supported.\n\
1025 \n\
1026 If a function is provided, its code object is used and all its state\n\
1027 is ignored, including its __globals__ dict.");
1028 
1029 static PyObject *
interp_call(PyObject * self,PyObject * args,PyObject * kwds)1030 interp_call(PyObject *self, PyObject *args, PyObject *kwds)
1031 {
1032     static char *kwlist[] = {"id", "callable", "args", "kwargs",
1033                              "restrict", NULL};
1034     PyObject *id, *callable;
1035     PyObject *args_obj = NULL;
1036     PyObject *kwargs_obj = NULL;
1037     int restricted = 0;
1038     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1039                                      "OO|OO$p:" MODULE_NAME_STR ".call", kwlist,
1040                                      &id, &callable, &args_obj, &kwargs_obj,
1041                                      &restricted))
1042     {
1043         return NULL;
1044     }
1045 
1046     int reqready = 1;
1047     PyInterpreterState *interp = \
1048             resolve_interp(id, restricted, reqready, "make a call in");
1049     if (interp == NULL) {
1050         return NULL;
1051     }
1052 
1053     if (args_obj != NULL) {
1054         PyErr_SetString(PyExc_ValueError, "got unexpected args");
1055         return NULL;
1056     }
1057     if (kwargs_obj != NULL) {
1058         PyErr_SetString(PyExc_ValueError, "got unexpected kwargs");
1059         return NULL;
1060     }
1061 
1062     PyObject *code = (PyObject *)convert_code_arg(callable, MODULE_NAME_STR ".call",
1063                                                   "argument 2", "a function");
1064     if (code == NULL) {
1065         return NULL;
1066     }
1067 
1068     PyObject *excinfo = NULL;
1069     int res = _interp_exec(self, interp, code, NULL, &excinfo);
1070     Py_DECREF(code);
1071     if (res < 0) {
1072         assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
1073         return excinfo;
1074     }
1075     Py_RETURN_NONE;
1076 }
1077 
1078 PyDoc_STRVAR(call_doc,
1079 "call(id, callable, args=None, kwargs=None, *, restrict=False)\n\
1080 \n\
1081 Call the provided object in the identified interpreter.\n\
1082 Pass the given args and kwargs, if possible.\n\
1083 \n\
1084 \"callable\" may be a plain function with no free vars that takes\n\
1085 no arguments.\n\
1086 \n\
1087 The function's code object is used and all its state\n\
1088 is ignored, including its __globals__ dict.");
1089 
1090 static PyObject *
interp_run_string(PyObject * self,PyObject * args,PyObject * kwds)1091 interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
1092 {
1093     static char *kwlist[] = {"id", "script", "shared", "restrict", NULL};
1094     PyObject *id, *script;
1095     PyObject *shared = NULL;
1096     int restricted = 0;
1097     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1098                                      "OU|O$p:" MODULE_NAME_STR ".run_string",
1099                                      kwlist, &id, &script, &shared, &restricted))
1100     {
1101         return NULL;
1102     }
1103 
1104     int reqready = 1;
1105     PyInterpreterState *interp = \
1106             resolve_interp(id, restricted, reqready, "run a string in");
1107     if (interp == NULL) {
1108         return NULL;
1109     }
1110 
1111     script = (PyObject *)convert_script_arg(script, MODULE_NAME_STR ".exec",
1112                                             "argument 2", "a string");
1113     if (script == NULL) {
1114         return NULL;
1115     }
1116 
1117     PyObject *excinfo = NULL;
1118     int res = _interp_exec(self, interp, script, shared, &excinfo);
1119     Py_DECREF(script);
1120     if (res < 0) {
1121         assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
1122         return excinfo;
1123     }
1124     Py_RETURN_NONE;
1125 }
1126 
1127 PyDoc_STRVAR(run_string_doc,
1128 "run_string(id, script, shared=None, *, restrict=False)\n\
1129 \n\
1130 Execute the provided string in the identified interpreter.\n\
1131 \n\
1132 (See " MODULE_NAME_STR ".exec().");
1133 
1134 static PyObject *
interp_run_func(PyObject * self,PyObject * args,PyObject * kwds)1135 interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
1136 {
1137     static char *kwlist[] = {"id", "func", "shared", "restrict", NULL};
1138     PyObject *id, *func;
1139     PyObject *shared = NULL;
1140     int restricted = 0;
1141     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1142                                      "OO|O$p:" MODULE_NAME_STR ".run_func",
1143                                      kwlist, &id, &func, &shared, &restricted))
1144     {
1145         return NULL;
1146     }
1147 
1148     int reqready = 1;
1149     PyInterpreterState *interp = \
1150             resolve_interp(id, restricted, reqready, "run a function in");
1151     if (interp == NULL) {
1152         return NULL;
1153     }
1154 
1155     PyCodeObject *code = convert_code_arg(func, MODULE_NAME_STR ".exec",
1156                                           "argument 2",
1157                                           "a function or a code object");
1158     if (code == NULL) {
1159         return NULL;
1160     }
1161 
1162     PyObject *excinfo = NULL;
1163     int res = _interp_exec(self, interp, (PyObject *)code, shared, &excinfo);
1164     Py_DECREF(code);
1165     if (res < 0) {
1166         assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
1167         return excinfo;
1168     }
1169     Py_RETURN_NONE;
1170 }
1171 
1172 PyDoc_STRVAR(run_func_doc,
1173 "run_func(id, func, shared=None, *, restrict=False)\n\
1174 \n\
1175 Execute the body of the provided function in the identified interpreter.\n\
1176 Code objects are also supported.  In both cases, closures and args\n\
1177 are not supported.  Methods and other callables are not supported either.\n\
1178 \n\
1179 (See " MODULE_NAME_STR ".exec().");
1180 
1181 
1182 static PyObject *
object_is_shareable(PyObject * self,PyObject * args,PyObject * kwds)1183 object_is_shareable(PyObject *self, PyObject *args, PyObject *kwds)
1184 {
1185     static char *kwlist[] = {"obj", NULL};
1186     PyObject *obj;
1187     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1188                                      "O:is_shareable", kwlist, &obj)) {
1189         return NULL;
1190     }
1191 
1192     if (_PyObject_CheckCrossInterpreterData(obj) == 0) {
1193         Py_RETURN_TRUE;
1194     }
1195     PyErr_Clear();
1196     Py_RETURN_FALSE;
1197 }
1198 
1199 PyDoc_STRVAR(is_shareable_doc,
1200 "is_shareable(obj) -> bool\n\
1201 \n\
1202 Return True if the object's data may be shared between interpreters and\n\
1203 False otherwise.");
1204 
1205 
1206 static PyObject *
interp_is_running(PyObject * self,PyObject * args,PyObject * kwds)1207 interp_is_running(PyObject *self, PyObject *args, PyObject *kwds)
1208 {
1209     static char *kwlist[] = {"id", "restrict", NULL};
1210     PyObject *id;
1211     int restricted = 0;
1212     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1213                                      "O|$p:is_running", kwlist,
1214                                      &id, &restricted))
1215     {
1216         return NULL;
1217     }
1218 
1219     int reqready = 1;
1220     PyInterpreterState *interp = \
1221             resolve_interp(id, restricted, reqready, "check if running for");
1222     if (interp == NULL) {
1223         return NULL;
1224     }
1225 
1226     if (is_running_main(interp)) {
1227         Py_RETURN_TRUE;
1228     }
1229     Py_RETURN_FALSE;
1230 }
1231 
1232 PyDoc_STRVAR(is_running_doc,
1233 "is_running(id, *, restrict=False) -> bool\n\
1234 \n\
1235 Return whether or not the identified interpreter is running.");
1236 
1237 
1238 static PyObject *
interp_get_config(PyObject * self,PyObject * args,PyObject * kwds)1239 interp_get_config(PyObject *self, PyObject *args, PyObject *kwds)
1240 {
1241     static char *kwlist[] = {"id", "restrict", NULL};
1242     PyObject *idobj = NULL;
1243     int restricted = 0;
1244     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1245                                      "O|$p:get_config", kwlist,
1246                                      &idobj, &restricted))
1247     {
1248         return NULL;
1249     }
1250     if (idobj == Py_None) {
1251         idobj = NULL;
1252     }
1253 
1254     int reqready = 0;
1255     PyInterpreterState *interp = \
1256             resolve_interp(idobj, restricted, reqready, "get the config of");
1257     if (interp == NULL) {
1258         return NULL;
1259     }
1260 
1261     PyInterpreterConfig config;
1262     if (_PyInterpreterConfig_InitFromState(&config, interp) < 0) {
1263         return NULL;
1264     }
1265     PyObject *dict = _PyInterpreterConfig_AsDict(&config);
1266     if (dict == NULL) {
1267         return NULL;
1268     }
1269 
1270     PyObject *configobj = _PyNamespace_New(dict);
1271     Py_DECREF(dict);
1272     return configobj;
1273 }
1274 
1275 PyDoc_STRVAR(get_config_doc,
1276 "get_config(id, *, restrict=False) -> types.SimpleNamespace\n\
1277 \n\
1278 Return a representation of the config used to initialize the interpreter.");
1279 
1280 
1281 static PyObject *
interp_whence(PyObject * self,PyObject * args,PyObject * kwds)1282 interp_whence(PyObject *self, PyObject *args, PyObject *kwds)
1283 {
1284     static char *kwlist[] = {"id", NULL};
1285     PyObject *id;
1286     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1287                                      "O:whence", kwlist, &id))
1288     {
1289         return NULL;
1290     }
1291 
1292     PyInterpreterState *interp = look_up_interp(id);
1293     if (interp == NULL) {
1294         return NULL;
1295     }
1296 
1297     long whence = get_whence(interp);
1298     return PyLong_FromLong(whence);
1299 }
1300 
1301 PyDoc_STRVAR(whence_doc,
1302 "whence(id) -> int\n\
1303 \n\
1304 Return an identifier for where the interpreter was created.");
1305 
1306 
1307 static PyObject *
interp_incref(PyObject * self,PyObject * args,PyObject * kwds)1308 interp_incref(PyObject *self, PyObject *args, PyObject *kwds)
1309 {
1310     static char *kwlist[] = {"id", "implieslink", "restrict", NULL};
1311     PyObject *id;
1312     int implieslink = 0;
1313     int restricted = 0;
1314     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1315                                      "O|$pp:incref", kwlist,
1316                                      &id, &implieslink, &restricted))
1317     {
1318         return NULL;
1319     }
1320 
1321     int reqready = 1;
1322     PyInterpreterState *interp = \
1323             resolve_interp(id, restricted, reqready, "incref");
1324     if (interp == NULL) {
1325         return NULL;
1326     }
1327 
1328     if (implieslink) {
1329         // Decref to 0 will destroy the interpreter.
1330         _PyInterpreterState_RequireIDRef(interp, 1);
1331     }
1332     _PyInterpreterState_IDIncref(interp);
1333 
1334     Py_RETURN_NONE;
1335 }
1336 
1337 
1338 static PyObject *
interp_decref(PyObject * self,PyObject * args,PyObject * kwds)1339 interp_decref(PyObject *self, PyObject *args, PyObject *kwds)
1340 {
1341     static char *kwlist[] = {"id", "restrict", NULL};
1342     PyObject *id;
1343     int restricted = 0;
1344     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1345                                      "O|$p:decref", kwlist, &id, &restricted))
1346     {
1347         return NULL;
1348     }
1349 
1350     int reqready = 1;
1351     PyInterpreterState *interp = \
1352             resolve_interp(id, restricted, reqready, "decref");
1353     if (interp == NULL) {
1354         return NULL;
1355     }
1356 
1357     _PyInterpreterState_IDDecref(interp);
1358 
1359     Py_RETURN_NONE;
1360 }
1361 
1362 
1363 static PyObject *
capture_exception(PyObject * self,PyObject * args,PyObject * kwds)1364 capture_exception(PyObject *self, PyObject *args, PyObject *kwds)
1365 {
1366     static char *kwlist[] = {"exc", NULL};
1367     PyObject *exc_arg = NULL;
1368     if (!PyArg_ParseTupleAndKeywords(args, kwds,
1369                                      "|O:capture_exception", kwlist,
1370                                      &exc_arg))
1371     {
1372         return NULL;
1373     }
1374 
1375     PyObject *exc = exc_arg;
1376     if (exc == NULL || exc == Py_None) {
1377         exc = PyErr_GetRaisedException();
1378         if (exc == NULL) {
1379             Py_RETURN_NONE;
1380         }
1381     }
1382     else if (!PyExceptionInstance_Check(exc)) {
1383         PyErr_Format(PyExc_TypeError, "expected exception, got %R", exc);
1384         return NULL;
1385     }
1386     PyObject *captured = NULL;
1387 
1388     _PyXI_excinfo info = {0};
1389     if (_PyXI_InitExcInfo(&info, exc) < 0) {
1390         goto finally;
1391     }
1392     captured = _PyXI_ExcInfoAsObject(&info);
1393     if (captured == NULL) {
1394         goto finally;
1395     }
1396 
1397     PyObject *formatted = _PyXI_FormatExcInfo(&info);
1398     if (formatted == NULL) {
1399         Py_CLEAR(captured);
1400         goto finally;
1401     }
1402     int res = PyObject_SetAttrString(captured, "formatted", formatted);
1403     Py_DECREF(formatted);
1404     if (res < 0) {
1405         Py_CLEAR(captured);
1406         goto finally;
1407     }
1408 
1409 finally:
1410     _PyXI_ClearExcInfo(&info);
1411     if (exc != exc_arg) {
1412         if (PyErr_Occurred()) {
1413             PyErr_SetRaisedException(exc);
1414         }
1415         else {
1416             _PyErr_ChainExceptions1(exc);
1417         }
1418     }
1419     return captured;
1420 }
1421 
1422 PyDoc_STRVAR(capture_exception_doc,
1423 "capture_exception(exc=None) -> types.SimpleNamespace\n\
1424 \n\
1425 Return a snapshot of an exception.  If \"exc\" is None\n\
1426 then the current exception, if any, is used (but not cleared).\n\
1427 \n\
1428 The returned snapshot is the same as what _interpreters.exec() returns.");
1429 
1430 
1431 static PyMethodDef module_functions[] = {
1432     {"new_config",                _PyCFunction_CAST(interp_new_config),
1433      METH_VARARGS | METH_KEYWORDS, new_config_doc},
1434 
1435     {"create",                    _PyCFunction_CAST(interp_create),
1436      METH_VARARGS | METH_KEYWORDS, create_doc},
1437     {"destroy",                   _PyCFunction_CAST(interp_destroy),
1438      METH_VARARGS | METH_KEYWORDS, destroy_doc},
1439     {"list_all",                  _PyCFunction_CAST(interp_list_all),
1440      METH_VARARGS | METH_KEYWORDS, list_all_doc},
1441     {"get_current",               interp_get_current,
1442      METH_NOARGS, get_current_doc},
1443     {"get_main",                  interp_get_main,
1444      METH_NOARGS, get_main_doc},
1445 
1446     {"is_running",                _PyCFunction_CAST(interp_is_running),
1447      METH_VARARGS | METH_KEYWORDS, is_running_doc},
1448     {"get_config",                _PyCFunction_CAST(interp_get_config),
1449      METH_VARARGS | METH_KEYWORDS, get_config_doc},
1450     {"whence",                    _PyCFunction_CAST(interp_whence),
1451      METH_VARARGS | METH_KEYWORDS, whence_doc},
1452     {"exec",                      _PyCFunction_CAST(interp_exec),
1453      METH_VARARGS | METH_KEYWORDS, exec_doc},
1454     {"call",                      _PyCFunction_CAST(interp_call),
1455      METH_VARARGS | METH_KEYWORDS, call_doc},
1456     {"run_string",                _PyCFunction_CAST(interp_run_string),
1457      METH_VARARGS | METH_KEYWORDS, run_string_doc},
1458     {"run_func",                  _PyCFunction_CAST(interp_run_func),
1459      METH_VARARGS | METH_KEYWORDS, run_func_doc},
1460 
1461     {"set___main___attrs",        _PyCFunction_CAST(interp_set___main___attrs),
1462      METH_VARARGS | METH_KEYWORDS, set___main___attrs_doc},
1463 
1464     {"incref",                    _PyCFunction_CAST(interp_incref),
1465      METH_VARARGS | METH_KEYWORDS, NULL},
1466     {"decref",                    _PyCFunction_CAST(interp_decref),
1467      METH_VARARGS | METH_KEYWORDS, NULL},
1468 
1469     {"is_shareable",              _PyCFunction_CAST(object_is_shareable),
1470      METH_VARARGS | METH_KEYWORDS, is_shareable_doc},
1471 
1472     {"capture_exception",         _PyCFunction_CAST(capture_exception),
1473      METH_VARARGS | METH_KEYWORDS, capture_exception_doc},
1474 
1475     {NULL,                        NULL}           /* sentinel */
1476 };
1477 
1478 
1479 /* initialization function */
1480 
1481 PyDoc_STRVAR(module_doc,
1482 "This module provides primitive operations to manage Python interpreters.\n\
1483 The 'interpreters' module provides a more convenient interface.");
1484 
1485 static int
module_exec(PyObject * mod)1486 module_exec(PyObject *mod)
1487 {
1488     PyInterpreterState *interp = PyInterpreterState_Get();
1489     module_state *state = get_module_state(mod);
1490 
1491 #define ADD_WHENCE(NAME) \
1492     if (PyModule_AddIntConstant(mod, "WHENCE_" #NAME,                   \
1493                                 _PyInterpreterState_WHENCE_##NAME) < 0) \
1494     {                                                                   \
1495         goto error;                                                     \
1496     }
1497     ADD_WHENCE(UNKNOWN)
1498     ADD_WHENCE(RUNTIME)
1499     ADD_WHENCE(LEGACY_CAPI)
1500     ADD_WHENCE(CAPI)
1501     ADD_WHENCE(XI)
1502     ADD_WHENCE(STDLIB)
1503 #undef ADD_WHENCE
1504 
1505     // exceptions
1506     if (PyModule_AddType(mod, (PyTypeObject *)PyExc_InterpreterError) < 0) {
1507         goto error;
1508     }
1509     if (PyModule_AddType(mod, (PyTypeObject *)PyExc_InterpreterNotFoundError) < 0) {
1510         goto error;
1511     }
1512     PyObject *PyExc_NotShareableError = \
1513                 _PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError;
1514     if (PyModule_AddType(mod, (PyTypeObject *)PyExc_NotShareableError) < 0) {
1515         goto error;
1516     }
1517 
1518     if (register_memoryview_xid(mod, &state->XIBufferViewType) < 0) {
1519         goto error;
1520     }
1521 
1522     return 0;
1523 
1524 error:
1525     return -1;
1526 }
1527 
1528 static struct PyModuleDef_Slot module_slots[] = {
1529     {Py_mod_exec, module_exec},
1530     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1531     {Py_mod_gil, Py_MOD_GIL_NOT_USED},
1532     {0, NULL},
1533 };
1534 
1535 static int
module_traverse(PyObject * mod,visitproc visit,void * arg)1536 module_traverse(PyObject *mod, visitproc visit, void *arg)
1537 {
1538     module_state *state = get_module_state(mod);
1539     assert(state != NULL);
1540     traverse_module_state(state, visit, arg);
1541     return 0;
1542 }
1543 
1544 static int
module_clear(PyObject * mod)1545 module_clear(PyObject *mod)
1546 {
1547     module_state *state = get_module_state(mod);
1548     assert(state != NULL);
1549     clear_module_state(state);
1550     return 0;
1551 }
1552 
1553 static void
module_free(void * mod)1554 module_free(void *mod)
1555 {
1556     module_state *state = get_module_state(mod);
1557     assert(state != NULL);
1558     clear_module_state(state);
1559 }
1560 
1561 static struct PyModuleDef moduledef = {
1562     .m_base = PyModuleDef_HEAD_INIT,
1563     .m_name = MODULE_NAME_STR,
1564     .m_doc = module_doc,
1565     .m_size = sizeof(module_state),
1566     .m_methods = module_functions,
1567     .m_slots = module_slots,
1568     .m_traverse = module_traverse,
1569     .m_clear = module_clear,
1570     .m_free = (freefunc)module_free,
1571 };
1572 
1573 PyMODINIT_FUNC
MODINIT_FUNC_NAME(void)1574 MODINIT_FUNC_NAME(void)
1575 {
1576     return PyModuleDef_Init(&moduledef);
1577 }
1578