From d299396293cc28f40f14445e56b365253a7cebe8 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 19 Mar 2024 13:31:33 -0600 Subject: [PATCH 1/7] Clean up interpreter ID conversions. --- Include/cpython/interpreteridobject.h | 4 ++ Modules/_xxsubinterpretersmodule.c | 80 +-------------------------- Objects/interpreteridobject.c | 67 +++++++++++++--------- 3 files changed, 48 insertions(+), 103 deletions(-) diff --git a/Include/cpython/interpreteridobject.h b/Include/cpython/interpreteridobject.h index 4ab9ad5d315f80..7e297a90d7c96e 100644 --- a/Include/cpython/interpreteridobject.h +++ b/Include/cpython/interpreteridobject.h @@ -9,3 +9,7 @@ PyAPI_DATA(PyTypeObject) PyInterpreterID_Type; PyAPI_FUNC(PyObject *) PyInterpreterID_New(int64_t); PyAPI_FUNC(PyObject *) PyInterpreterState_GetIDObject(PyInterpreterState *); PyAPI_FUNC(PyInterpreterState *) PyInterpreterID_LookUp(PyObject *); + +#ifndef Py_BUILD_CORE +extern int64_t _PyInterpreterID_ObjectToID(PyObject *); +#endif diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 28c2f9c08bc0da..a5f1dadb8ebefc 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -35,84 +35,9 @@ _get_current_interp(void) return PyInterpreterState_Get(); } -static int64_t -pylong_to_interpid(PyObject *idobj) -{ - assert(PyLong_CheckExact(idobj)); - - if (_PyLong_IsNegative((PyLongObject *)idobj)) { - PyErr_Format(PyExc_ValueError, - "interpreter ID must be a non-negative int, got %R", - idobj); - return -1; - } - - int overflow; - long long id = PyLong_AsLongLongAndOverflow(idobj, &overflow); - if (id == -1) { - if (!overflow) { - assert(PyErr_Occurred()); - return -1; - } - assert(!PyErr_Occurred()); - // For now, we don't worry about if LLONG_MAX < INT64_MAX. - goto bad_id; - } -#if LLONG_MAX > INT64_MAX - if (id > INT64_MAX) { - goto bad_id; - } -#endif - return (int64_t)id; - -bad_id: - PyErr_Format(PyExc_RuntimeError, - "unrecognized interpreter ID %O", idobj); - return -1; -} - -static int64_t -convert_interpid_obj(PyObject *arg) -{ - int64_t id = -1; - if (_PyIndex_Check(arg)) { - PyObject *idobj = PyNumber_Long(arg); - if (idobj == NULL) { - return -1; - } - id = pylong_to_interpid(idobj); - Py_DECREF(idobj); - if (id < 0) { - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, - "interpreter ID must be an int, got %.100s", - Py_TYPE(arg)->tp_name); - return -1; - } - return id; -} - -static PyInterpreterState * -look_up_interp(PyObject *arg) -{ - int64_t id = convert_interpid_obj(arg); - if (id < 0) { - return NULL; - } - return _PyInterpreterState_LookUpID(id); -} +#define look_up_interp PyInterpreterID_LookUp -static PyObject * -interpid_to_pylong(int64_t id) -{ - assert(id < LLONG_MAX); - return PyLong_FromLongLong(id); -} - static PyObject * get_interpid_obj(PyInterpreterState *interp) { @@ -123,7 +48,8 @@ get_interpid_obj(PyInterpreterState *interp) if (id < 0) { return NULL; } - return interpid_to_pylong(id); + assert(id < LLONG_MAX); + return PyLong_FromLongLong(id); } static PyObject * diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 16e27b64c0c9c2..5322bd03a59b8c 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -42,43 +42,58 @@ newinterpid(PyTypeObject *cls, int64_t id, int force) return self; } -static int -interp_id_converter(PyObject *arg, void *ptr) +int64_t +_PyInterpreterID_ObjectToID(PyObject *idobj) { - int64_t id; - if (PyObject_TypeCheck(arg, &PyInterpreterID_Type)) { - id = ((interpid *)arg)->id; - } - else if (_PyIndex_Check(arg)) { - id = PyLong_AsLongLong(arg); - if (id == -1 && PyErr_Occurred()) { - return 0; - } - if (id < 0) { - PyErr_Format(PyExc_ValueError, - "interpreter ID must be a non-negative int, got %R", arg); - return 0; - } + if (PyObject_TypeCheck(idobj, &PyInterpreterID_Type)) { + assert(((interpid *)idobj)->id >= 0); + return ((interpid *)idobj)->id; } - else { + + if (!_PyIndex_Check(idobj)) { PyErr_Format(PyExc_TypeError, "interpreter ID must be an int, got %.100s", - Py_TYPE(arg)->tp_name); - return 0; + Py_TYPE(idobj)->tp_name); + return -1; + } + + // This may raise OverflowError. + // For now, we don't worry about if LLONG_MAX < INT64_MAX. + long long id = PyLong_AsLongLong(idobj); + if (id == -1 && PyErr_Occurred()) { + return -1; + } + + if (id < 0) { + PyErr_Format(PyExc_ValueError, + "interpreter ID must be a non-negative int, got %R", + idobj); + return -1; + } +#if LLONG_MAX > INT64_MAX + else if (id > INT64_MAX) { + PyErr_SetString(PyExc_OverflowError, "int too big to convert"); + return -1; + } +#endif + else { + return (int64_t)id; } - *(int64_t *)ptr = id; - return 1; } static PyObject * interpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"id", "force", NULL}; - int64_t id; + PyObject *idobj; int force = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O&|$p:InterpreterID.__init__", kwlist, - interp_id_converter, &id, &force)) { + "O|$p:InterpreterID.__init__", kwlist, + &idobj, &force)) { + return NULL; + } + int64_t id = _PyInterpreterID_ObjectToID(idobj); + if (id < 0) { return NULL; } @@ -286,8 +301,8 @@ PyInterpreterState_GetIDObject(PyInterpreterState *interp) PyInterpreterState * PyInterpreterID_LookUp(PyObject *requested_id) { - int64_t id; - if (!interp_id_converter(requested_id, &id)) { + int64_t id = _PyInterpreterID_ObjectToID(requested_id); + if (id < 0) { return NULL; } return _PyInterpreterState_LookUpID(id); From 98690109c07dc5048d2665e659fc7ad3f7fb8974 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 20 Mar 2024 09:38:39 -0600 Subject: [PATCH 2/7] Add a section specifically about interpreter ID. --- Python/pystate.c | 53 ++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/Python/pystate.c b/Python/pystate.c index eedcb920cd1cf2..35cc4f7c94625b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1064,6 +1064,35 @@ _PyInterpreterState_FailIfRunningMain(PyInterpreterState *interp) // accessors //---------- +PyObject * +PyUnstable_InterpreterState_GetMainModule(PyInterpreterState *interp) +{ + PyObject *modules = _PyImport_GetModules(interp); + if (modules == NULL) { + PyErr_SetString(PyExc_RuntimeError, "interpreter not initialized"); + return NULL; + } + return PyMapping_GetItemString(modules, "__main__"); +} + +PyObject * +PyInterpreterState_GetDict(PyInterpreterState *interp) +{ + if (interp->dict == NULL) { + interp->dict = PyDict_New(); + if (interp->dict == NULL) { + PyErr_Clear(); + } + } + /* Returning NULL means no per-interpreter dict is available. */ + return interp->dict; +} + + +//---------- +// interp ID +//---------- + int64_t PyInterpreterState_GetID(PyInterpreterState *interp) { @@ -1142,30 +1171,6 @@ _PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required) interp->requires_idref = required ? 1 : 0; } -PyObject * -PyUnstable_InterpreterState_GetMainModule(PyInterpreterState *interp) -{ - PyObject *modules = _PyImport_GetModules(interp); - if (modules == NULL) { - PyErr_SetString(PyExc_RuntimeError, "interpreter not initialized"); - return NULL; - } - return PyMapping_GetItemString(modules, "__main__"); -} - -PyObject * -PyInterpreterState_GetDict(PyInterpreterState *interp) -{ - if (interp->dict == NULL) { - interp->dict = PyDict_New(); - if (interp->dict == NULL) { - PyErr_Clear(); - } - } - /* Returning NULL means no per-interpreter dict is available. */ - return interp->dict; -} - //----------------------------- // look up an interpreter state From 76db4365526997dcce9de4a3db217e2cd4d33b16 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 20 Mar 2024 10:03:14 -0600 Subject: [PATCH 3/7] Add _PyInterpreterID_GetID(). --- Include/cpython/interpreteridobject.h | 3 ++- Objects/interpreteridobject.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Include/cpython/interpreteridobject.h b/Include/cpython/interpreteridobject.h index 7e297a90d7c96e..08472b899f4967 100644 --- a/Include/cpython/interpreteridobject.h +++ b/Include/cpython/interpreteridobject.h @@ -10,6 +10,7 @@ PyAPI_FUNC(PyObject *) PyInterpreterID_New(int64_t); PyAPI_FUNC(PyObject *) PyInterpreterState_GetIDObject(PyInterpreterState *); PyAPI_FUNC(PyInterpreterState *) PyInterpreterID_LookUp(PyObject *); -#ifndef Py_BUILD_CORE +#ifdef Py_BUILD_CORE +extern int64_t _PyInterpreterID_GetID(PyObject *); extern int64_t _PyInterpreterID_ObjectToID(PyObject *); #endif diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 5322bd03a59b8c..ab6cf2b7d6e3cb 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -11,6 +11,21 @@ typedef struct interpid { int64_t id; } interpid; +int64_t +_PyInterpreterID_GetID(PyObject *self) +{ + if (!PyObject_TypeCheck(self, &PyInterpreterID_Type)) { + PyErr_Format(PyExc_TypeError, + "expected an InterpreterID, got %R", + self); + return -1; + + } + int64_t id = ((interpid *)self)->id; + assert(id >= 0); + return id; +} + static interpid * newinterpid(PyTypeObject *cls, int64_t id, int force) { From a10fe2aec4628d03d43980c288741a222675b579 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 20 Mar 2024 10:03:55 -0600 Subject: [PATCH 4/7] _PyInterpreterID_ObjectToID() -> _PyInterpreterState_ObjectToID() --- Include/cpython/interpreteridobject.h | 1 - Include/internal/pycore_interp.h | 2 ++ Objects/interpreteridobject.c | 46 ++------------------------- Python/pystate.c | 40 +++++++++++++++++++++++ 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/Include/cpython/interpreteridobject.h b/Include/cpython/interpreteridobject.h index 08472b899f4967..552b65bb6c5689 100644 --- a/Include/cpython/interpreteridobject.h +++ b/Include/cpython/interpreteridobject.h @@ -12,5 +12,4 @@ PyAPI_FUNC(PyInterpreterState *) PyInterpreterID_LookUp(PyObject *); #ifdef Py_BUILD_CORE extern int64_t _PyInterpreterID_GetID(PyObject *); -extern int64_t _PyInterpreterID_ObjectToID(PyObject *); #endif diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 942f47340b3966..082177f84c3690 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -295,6 +295,8 @@ _PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tst } +extern int64_t _PyInterpreterState_ObjectToID(PyObject *); + // Export for the _xxinterpchannels module. PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t); diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index ab6cf2b7d6e3cb..6e9fa2876a0ec5 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -1,8 +1,7 @@ /* InterpreterID object */ #include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_interp.h" // _PyInterpreterState_LookUpID() +#include "pycore_interp.h" // _PyInterpreterState_LookUpID() #include "interpreteridobject.h" @@ -57,45 +56,6 @@ newinterpid(PyTypeObject *cls, int64_t id, int force) return self; } -int64_t -_PyInterpreterID_ObjectToID(PyObject *idobj) -{ - if (PyObject_TypeCheck(idobj, &PyInterpreterID_Type)) { - assert(((interpid *)idobj)->id >= 0); - return ((interpid *)idobj)->id; - } - - if (!_PyIndex_Check(idobj)) { - PyErr_Format(PyExc_TypeError, - "interpreter ID must be an int, got %.100s", - Py_TYPE(idobj)->tp_name); - return -1; - } - - // This may raise OverflowError. - // For now, we don't worry about if LLONG_MAX < INT64_MAX. - long long id = PyLong_AsLongLong(idobj); - if (id == -1 && PyErr_Occurred()) { - return -1; - } - - if (id < 0) { - PyErr_Format(PyExc_ValueError, - "interpreter ID must be a non-negative int, got %R", - idobj); - return -1; - } -#if LLONG_MAX > INT64_MAX - else if (id > INT64_MAX) { - PyErr_SetString(PyExc_OverflowError, "int too big to convert"); - return -1; - } -#endif - else { - return (int64_t)id; - } -} - static PyObject * interpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) { @@ -107,7 +67,7 @@ interpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) &idobj, &force)) { return NULL; } - int64_t id = _PyInterpreterID_ObjectToID(idobj); + int64_t id = _PyInterpreterState_ObjectToID(idobj); if (id < 0) { return NULL; } @@ -316,7 +276,7 @@ PyInterpreterState_GetIDObject(PyInterpreterState *interp) PyInterpreterState * PyInterpreterID_LookUp(PyObject *requested_id) { - int64_t id = _PyInterpreterID_ObjectToID(requested_id); + int64_t id = _PyInterpreterState_ObjectToID(requested_id); if (id < 0) { return NULL; } diff --git a/Python/pystate.c b/Python/pystate.c index 35cc4f7c94625b..d1bd305ce26c7f 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -2,6 +2,8 @@ /* Thread and interpreter state structures and their interfaces */ #include "Python.h" +#include "interpreteridobject.h" // PyInterpreterID_Type +#include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_ceval.h" #include "pycore_code.h" // stats #include "pycore_critical_section.h" // _PyCriticalSection_Resume() @@ -1093,6 +1095,44 @@ PyInterpreterState_GetDict(PyInterpreterState *interp) // interp ID //---------- +int64_t +_PyInterpreterState_ObjectToID(PyObject *idobj) +{ + if (PyObject_TypeCheck(idobj, &PyInterpreterID_Type)) { + return _PyInterpreterID_GetID(idobj); + } + + if (!_PyIndex_Check(idobj)) { + PyErr_Format(PyExc_TypeError, + "interpreter ID must be an int, got %.100s", + Py_TYPE(idobj)->tp_name); + return -1; + } + + // This may raise OverflowError. + // For now, we don't worry about if LLONG_MAX < INT64_MAX. + long long id = PyLong_AsLongLong(idobj); + if (id == -1 && PyErr_Occurred()) { + return -1; + } + + if (id < 0) { + PyErr_Format(PyExc_ValueError, + "interpreter ID must be a non-negative int, got %R", + idobj); + return -1; + } +#if LLONG_MAX > INT64_MAX + else if (id > INT64_MAX) { + PyErr_SetString(PyExc_OverflowError, "int too big to convert"); + return -1; + } +#endif + else { + return (int64_t)id; + } +} + int64_t PyInterpreterState_GetID(PyInterpreterState *interp) { From 7154bb663c2f166f29ae50f65aff08c25c610085 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 20 Mar 2024 10:20:04 -0600 Subject: [PATCH 5/7] PyInterpreterID_LookUp() -> PyInterpreterState_LookUpIDObject() --- Include/cpython/interpreteridobject.h | 1 - Include/internal/pycore_interp.h | 1 + Lib/test/test_capi/test_misc.py | 4 ++-- Modules/_testcapimodule.c | 26 --------------------- Modules/_testinternalcapi.c | 33 +++++++++++++++++++++++---- Modules/_xxsubinterpretersmodule.c | 4 ++-- Objects/interpreteridobject.c | 10 -------- Python/pystate.c | 10 ++++++++ 8 files changed, 44 insertions(+), 45 deletions(-) diff --git a/Include/cpython/interpreteridobject.h b/Include/cpython/interpreteridobject.h index 552b65bb6c5689..d425c909806e44 100644 --- a/Include/cpython/interpreteridobject.h +++ b/Include/cpython/interpreteridobject.h @@ -8,7 +8,6 @@ PyAPI_DATA(PyTypeObject) PyInterpreterID_Type; PyAPI_FUNC(PyObject *) PyInterpreterID_New(int64_t); PyAPI_FUNC(PyObject *) PyInterpreterState_GetIDObject(PyInterpreterState *); -PyAPI_FUNC(PyInterpreterState *) PyInterpreterID_LookUp(PyObject *); #ifdef Py_BUILD_CORE extern int64_t _PyInterpreterID_GetID(PyObject *); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 082177f84c3690..86f49221de01f3 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -299,6 +299,7 @@ extern int64_t _PyInterpreterState_ObjectToID(PyObject *); // Export for the _xxinterpchannels module. PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_LookUpIDObject(PyObject *); PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 7365ead1c4749c..089e5f42a8357f 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -2185,7 +2185,7 @@ def test_equality(self): def test_linked_lifecycle(self): id1 = _interpreters.create() - _testcapi.unlink_interpreter_refcount(id1) + _testinternalcapi.unlink_interpreter_refcount(id1) self.assertEqual( _testinternalcapi.get_interpreter_refcount(id1), 0) @@ -2201,7 +2201,7 @@ def test_linked_lifecycle(self): _testinternalcapi.get_interpreter_refcount(id1), 0) - _testcapi.link_interpreter_refcount(id1) + _testinternalcapi.link_interpreter_refcount(id1) self.assertEqual( _testinternalcapi.get_interpreter_refcount(id1), 0) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 7928cd7d6fe1ae..b180c6f5bf4c06 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1455,30 +1455,6 @@ get_interpreterid_type(PyObject *self, PyObject *Py_UNUSED(ignored)) return Py_NewRef(&PyInterpreterID_Type); } -static PyObject * -link_interpreter_refcount(PyObject *self, PyObject *idobj) -{ - PyInterpreterState *interp = PyInterpreterID_LookUp(idobj); - if (interp == NULL) { - assert(PyErr_Occurred()); - return NULL; - } - _PyInterpreterState_RequireIDRef(interp, 1); - Py_RETURN_NONE; -} - -static PyObject * -unlink_interpreter_refcount(PyObject *self, PyObject *idobj) -{ - PyInterpreterState *interp = PyInterpreterID_LookUp(idobj); - if (interp == NULL) { - assert(PyErr_Occurred()); - return NULL; - } - _PyInterpreterState_RequireIDRef(interp, 0); - Py_RETURN_NONE; -} - static PyMethodDef ml; static PyObject * @@ -3297,8 +3273,6 @@ static PyMethodDef TestMethods[] = { {"test_current_tstate_matches", test_current_tstate_matches, METH_NOARGS}, {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, {"get_interpreterid_type", get_interpreterid_type, METH_NOARGS}, - {"link_interpreter_refcount", link_interpreter_refcount, METH_O}, - {"unlink_interpreter_refcount", unlink_interpreter_refcount, METH_O}, {"create_cfunction", create_cfunction, METH_NOARGS}, {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_VARARGS, PyDoc_STR("set_error_class(error_class) -> None")}, diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 1c10dd02138f3a..2a33c3797341a5 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -29,8 +29,6 @@ #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "interpreteridobject.h" // PyInterpreterID_LookUp() - #include "clinic/_testinternalcapi.c.h" // Include test definitions from _testinternalcapi/ @@ -1112,7 +1110,7 @@ pending_identify(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O:pending_identify", &interpid)) { return NULL; } - PyInterpreterState *interp = PyInterpreterID_LookUp(interpid); + PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(interpid); if (interp == NULL) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "interpreter not found"); @@ -1378,6 +1376,31 @@ dict_getitem_knownhash(PyObject *self, PyObject *args) } +static PyObject * +link_interpreter_refcount(PyObject *self, PyObject *idobj) +{ + PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); + if (interp == NULL) { + assert(PyErr_Occurred()); + return NULL; + } + _PyInterpreterState_RequireIDRef(interp, 1); + Py_RETURN_NONE; +} + +static PyObject * +unlink_interpreter_refcount(PyObject *self, PyObject *idobj) +{ + PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); + if (interp == NULL) { + assert(PyErr_Occurred()); + return NULL; + } + _PyInterpreterState_RequireIDRef(interp, 0); + Py_RETURN_NONE; +} + + /* To run some code in a sub-interpreter. */ static PyObject * run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) @@ -1480,7 +1503,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) static PyObject * get_interpreter_refcount(PyObject *self, PyObject *idobj) { - PyInterpreterState *interp = PyInterpreterID_LookUp(idobj); + PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); if (interp == NULL) { return NULL; } @@ -1724,6 +1747,8 @@ static PyMethodDef module_functions[] = { {"get_object_dict_values", get_object_dict_values, METH_O}, {"hamt", new_hamt, METH_NOARGS}, {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, + {"link_interpreter_refcount", link_interpreter_refcount, METH_O}, + {"unlink_interpreter_refcount", unlink_interpreter_refcount, METH_O}, {"run_in_subinterp_with_config", _PyCFunction_CAST(run_in_subinterp_with_config), METH_VARARGS | METH_KEYWORDS}, diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index a5f1dadb8ebefc..106daaba264e0f 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -35,7 +35,7 @@ _get_current_interp(void) return PyInterpreterState_Get(); } -#define look_up_interp PyInterpreterID_LookUp +#define look_up_interp PyInterpreterState_LookUpIDObject static PyObject * @@ -625,7 +625,7 @@ interp_set___main___attrs(PyObject *self, PyObject *args) } // Look up the interpreter. - PyInterpreterState *interp = PyInterpreterID_LookUp(id); + PyInterpreterState *interp = look_up_interp(id); if (interp == NULL) { return NULL; } diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 6e9fa2876a0ec5..4844d6a9bf781c 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -272,13 +272,3 @@ PyInterpreterState_GetIDObject(PyInterpreterState *interp) } return (PyObject *)newinterpid(&PyInterpreterID_Type, id, 0); } - -PyInterpreterState * -PyInterpreterID_LookUp(PyObject *requested_id) -{ - int64_t id = _PyInterpreterState_ObjectToID(requested_id); - if (id < 0) { - return NULL; - } - return _PyInterpreterState_LookUpID(id); -} diff --git a/Python/pystate.c b/Python/pystate.c index d1bd305ce26c7f..dc4582dd86644a 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1272,6 +1272,16 @@ _PyInterpreterState_LookUpID(int64_t requested_id) return interp; } +PyInterpreterState * +PyInterpreterState_LookUpIDObject(PyObject *requested_id) +{ + int64_t id = _PyInterpreterState_ObjectToID(requested_id); + if (id < 0) { + return NULL; + } + return _PyInterpreterState_LookUpID(id); +} + /********************************/ /* the per-thread runtime state */ From 6f9e5eca6488de6fee95cd162f215a2231f7cd5f Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 20 Mar 2024 10:30:27 -0600 Subject: [PATCH 6/7] Move functions to the right place. --- Modules/_testinternalcapi.c | 53 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 2a33c3797341a5..bad094a0445477 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1376,31 +1376,6 @@ dict_getitem_knownhash(PyObject *self, PyObject *args) } -static PyObject * -link_interpreter_refcount(PyObject *self, PyObject *idobj) -{ - PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); - if (interp == NULL) { - assert(PyErr_Occurred()); - return NULL; - } - _PyInterpreterState_RequireIDRef(interp, 1); - Py_RETURN_NONE; -} - -static PyObject * -unlink_interpreter_refcount(PyObject *self, PyObject *idobj) -{ - PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); - if (interp == NULL) { - assert(PyErr_Occurred()); - return NULL; - } - _PyInterpreterState_RequireIDRef(interp, 0); - Py_RETURN_NONE; -} - - /* To run some code in a sub-interpreter. */ static PyObject * run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) @@ -1510,6 +1485,30 @@ get_interpreter_refcount(PyObject *self, PyObject *idobj) return PyLong_FromLongLong(interp->id_refcount); } +static PyObject * +link_interpreter_refcount(PyObject *self, PyObject *idobj) +{ + PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); + if (interp == NULL) { + assert(PyErr_Occurred()); + return NULL; + } + _PyInterpreterState_RequireIDRef(interp, 1); + Py_RETURN_NONE; +} + +static PyObject * +unlink_interpreter_refcount(PyObject *self, PyObject *idobj) +{ + PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); + if (interp == NULL) { + assert(PyErr_Occurred()); + return NULL; + } + _PyInterpreterState_RequireIDRef(interp, 0); + Py_RETURN_NONE; +} + static void _xid_capsule_destructor(PyObject *capsule) @@ -1747,12 +1746,12 @@ static PyMethodDef module_functions[] = { {"get_object_dict_values", get_object_dict_values, METH_O}, {"hamt", new_hamt, METH_NOARGS}, {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, - {"link_interpreter_refcount", link_interpreter_refcount, METH_O}, - {"unlink_interpreter_refcount", unlink_interpreter_refcount, METH_O}, {"run_in_subinterp_with_config", _PyCFunction_CAST(run_in_subinterp_with_config), METH_VARARGS | METH_KEYWORDS}, {"get_interpreter_refcount", get_interpreter_refcount, METH_O}, + {"link_interpreter_refcount", link_interpreter_refcount, METH_O}, + {"unlink_interpreter_refcount", unlink_interpreter_refcount, METH_O}, {"compile_perf_trampoline_entry", compile_perf_trampoline_entry, METH_VARARGS}, {"perf_trampoline_set_persist_after_fork", perf_trampoline_set_persist_after_fork, METH_VARARGS}, {"get_crossinterp_data", get_crossinterp_data, METH_VARARGS}, From 1d3e30fd5dbb7f96c87d361c1b492c14891c1379 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 20 Mar 2024 11:21:21 -0600 Subject: [PATCH 7/7] PyInterpreterState_LookUpIDObject() -> _PyInterpreterState_LookUpIDObject() --- Include/internal/pycore_interp.h | 2 +- Modules/_testinternalcapi.c | 8 ++++---- Modules/_xxsubinterpretersmodule.c | 2 +- Python/pystate.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 86f49221de01f3..b28e8a3ff45f3f 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -299,7 +299,7 @@ extern int64_t _PyInterpreterState_ObjectToID(PyObject *); // Export for the _xxinterpchannels module. PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t); -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_LookUpIDObject(PyObject *); +PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpIDObject(PyObject *); PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index bad094a0445477..f73a29e5afe801 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1110,7 +1110,7 @@ pending_identify(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O:pending_identify", &interpid)) { return NULL; } - PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(interpid); + PyInterpreterState *interp = _PyInterpreterState_LookUpIDObject(interpid); if (interp == NULL) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "interpreter not found"); @@ -1478,7 +1478,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) static PyObject * get_interpreter_refcount(PyObject *self, PyObject *idobj) { - PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); + PyInterpreterState *interp = _PyInterpreterState_LookUpIDObject(idobj); if (interp == NULL) { return NULL; } @@ -1488,7 +1488,7 @@ get_interpreter_refcount(PyObject *self, PyObject *idobj) static PyObject * link_interpreter_refcount(PyObject *self, PyObject *idobj) { - PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); + PyInterpreterState *interp = _PyInterpreterState_LookUpIDObject(idobj); if (interp == NULL) { assert(PyErr_Occurred()); return NULL; @@ -1500,7 +1500,7 @@ link_interpreter_refcount(PyObject *self, PyObject *idobj) static PyObject * unlink_interpreter_refcount(PyObject *self, PyObject *idobj) { - PyInterpreterState *interp = PyInterpreterState_LookUpIDObject(idobj); + PyInterpreterState *interp = _PyInterpreterState_LookUpIDObject(idobj); if (interp == NULL) { assert(PyErr_Occurred()); return NULL; diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 106daaba264e0f..606b2a36481ce2 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -35,7 +35,7 @@ _get_current_interp(void) return PyInterpreterState_Get(); } -#define look_up_interp PyInterpreterState_LookUpIDObject +#define look_up_interp _PyInterpreterState_LookUpIDObject static PyObject * diff --git a/Python/pystate.c b/Python/pystate.c index dc4582dd86644a..2e2781cd585a8e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1273,7 +1273,7 @@ _PyInterpreterState_LookUpID(int64_t requested_id) } PyInterpreterState * -PyInterpreterState_LookUpIDObject(PyObject *requested_id) +_PyInterpreterState_LookUpIDObject(PyObject *requested_id) { int64_t id = _PyInterpreterState_ObjectToID(requested_id); if (id < 0) {