Skip to content

Commit 61f70ae

Browse files
committed
Add a test for weak interpreter references.
1 parent 082fd69 commit 61f70ae

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

Modules/_testcapimodule.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "frameobject.h" // PyFrame_New()
1616
#include "marshal.h" // PyMarshal_WriteLongToFile()
17+
#include "pyerrors.h"
1718
#include "pylifecycle.h"
1819
#include "pystate.h"
1920

@@ -2656,6 +2657,10 @@ test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
26562657
PyInterpreterRef ref = get_strong_ref();
26572658
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
26582659
PyThreadState *interp_tstate = Py_NewInterpreter();
2660+
if (interp_tstate == NULL) {
2661+
PyInterpreterRef_Close(ref);
2662+
return PyErr_NoMemory();
2663+
}
26592664

26602665
/* This should create a new thread state for the calling interpreter, *not*
26612666
reactivate the old one. In a real-world scenario, this would arise in
@@ -2702,6 +2707,36 @@ test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
27022707
Py_RETURN_NONE;
27032708
}
27042709

2710+
static PyObject *
2711+
test_weak_interpreter_ref_after_shutdown(PyObject *self, PyObject *unused)
2712+
{
2713+
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
2714+
PyInterpreterWeakRef wref;
2715+
PyThreadState *interp_tstate = Py_NewInterpreter();
2716+
if (interp_tstate == NULL) {
2717+
return PyErr_NoMemory();
2718+
}
2719+
2720+
int res = PyInterpreterWeakRef_Get(&wref);
2721+
(void)res;
2722+
assert(res == 0);
2723+
2724+
// As a sanity check, ensure that the weakref actually works
2725+
PyInterpreterRef ref;
2726+
res = PyInterpreterWeakRef_AsStrong(wref, &ref);
2727+
assert(res == 0);
2728+
PyInterpreterRef_Close(ref);
2729+
2730+
// Now, destroy the interpreter and try to acquire a weak reference.
2731+
// It should fail.
2732+
Py_EndInterpreter(interp_tstate);
2733+
res = PyInterpreterWeakRef_AsStrong(wref, &ref);
2734+
assert(res == -1);
2735+
2736+
PyThreadState_Swap(save_tstate);
2737+
Py_RETURN_NONE;
2738+
}
2739+
27052740
static PyMethodDef TestMethods[] = {
27062741
{"set_errno", set_errno, METH_VARARGS},
27072742
{"test_config", test_config, METH_NOARGS},
@@ -2799,6 +2834,7 @@ static PyMethodDef TestMethods[] = {
27992834
{"test_interpreter_refs", test_interpreter_refs, METH_NOARGS},
28002835
{"test_thread_state_ensure_nested", test_thread_state_ensure_nested, METH_NOARGS},
28012836
{"test_thread_state_ensure_crossinterp", test_thread_state_ensure_crossinterp, METH_NOARGS},
2837+
{"test_weak_interpreter_ref_after_shutdown", test_weak_interpreter_ref_after_shutdown, METH_NOARGS},
28022838
{NULL, NULL} /* sentinel */
28032839
};
28042840

0 commit comments

Comments
 (0)