From 176b42ac44ae5f0fd88f6876b985aa0751ec81e2 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 12 May 2024 15:20:30 +0300 Subject: [PATCH 1/4] gh-118965: Share `NotImplemented` in subinterpreters --- Lib/test/test__interpreters.py | 5 ++-- ...-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst | 1 + Python/crossinterp_data_lookup.h | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst diff --git a/Lib/test/test__interpreters.py b/Lib/test/test__interpreters.py index beeb280894ea99..81f622c27a20c1 100644 --- a/Lib/test/test__interpreters.py +++ b/Lib/test/test__interpreters.py @@ -99,6 +99,7 @@ def test_default_shareables(self): shareables = [ # singletons None, + NotImplemented, # builtin objects b'spam', 'spam', @@ -126,7 +127,6 @@ class SubBytes(bytes): not_shareables = [ # singletons - NotImplemented, ..., # builtin types and objects type, @@ -156,13 +156,14 @@ def _assert_values(self, values): self.assertIs(type(got), type(obj)) def test_singletons(self): - for obj in [None]: + for obj in [None, NotImplemented]: with self.subTest(obj): xid = _testinternalcapi.get_crossinterp_data(obj) got = _testinternalcapi.restore_crossinterp_data(xid) # XXX What about between interpreters? self.assertIs(got, obj) + self.assertIs(type(got), type(obj)) def test_types(self): self._assert_values([ diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst new file mode 100644 index 00000000000000..f2f64e0329e240 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst @@ -0,0 +1 @@ +Added support for sharing ``NotImplemented`` singleton with subinterpreters. diff --git a/Python/crossinterp_data_lookup.h b/Python/crossinterp_data_lookup.h index 863919ad42fb97..78e5daa0253551 100644 --- a/Python/crossinterp_data_lookup.h +++ b/Python/crossinterp_data_lookup.h @@ -435,6 +435,23 @@ _none_shared(PyThreadState *tstate, PyObject *obj, return 0; } +// NotImplemented + +static PyObject * +_new_notimplemented_object(_PyCrossInterpreterData *data) +{ + return Py_NewRef(Py_NotImplemented); +} + +static int +_notimplemented_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + _PyCrossInterpreterData_Init(data, tstate->interp, NULL, NULL, + _new_notimplemented_object); + return 0; +} + // bool static PyObject * @@ -562,6 +579,13 @@ _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) Py_FatalError("could not register None for cross-interpreter sharing"); } + // NotImplemented + if (_xidregistry_add_type(xidregistry, + (PyTypeObject *)PyObject_Type(Py_NotImplemented), + _notimplemented_shared) != 0) { + Py_FatalError("could not register NotImplemented for cross-interpreter sharing"); + } + // int if (_xidregistry_add_type(xidregistry, &PyLong_Type, _long_shared) != 0) { Py_FatalError("could not register int for cross-interpreter sharing"); From 0320a418e4c81bc902fa6ae14080385597e4b9c8 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 12 May 2024 16:41:26 +0300 Subject: [PATCH 2/4] Fix CI --- Lib/test/test_interpreters/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_interpreters/test_api.py b/Lib/test/test_interpreters/test_api.py index 719c1c721cad7c..25aa1b94bcbe7e 100644 --- a/Lib/test/test_interpreters/test_api.py +++ b/Lib/test/test_interpreters/test_api.py @@ -1099,6 +1099,7 @@ def test_default_shareables(self): shareables = [ # singletons None, + NotImplemented, # builtin objects b'spam', 'spam', @@ -1127,7 +1128,6 @@ class SubBytes(bytes): not_shareables = [ # singletons - NotImplemented, ..., # builtin types and objects type, From 99ae55755732eed3efc2224d14fb30733a457c9c Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 9 Feb 2025 18:17:03 +0300 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Peter Bierma --- .../2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst | 2 +- Python/crossinterp_data_lookup.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst index f2f64e0329e240..dbcd40f897aa13 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst @@ -1 +1 @@ -Added support for sharing ``NotImplemented`` singleton with subinterpreters. +Added support for sharing :data:`NotImplemented` singleton between subinterpreters. diff --git a/Python/crossinterp_data_lookup.h b/Python/crossinterp_data_lookup.h index 78e5daa0253551..aaa354a20100f9 100644 --- a/Python/crossinterp_data_lookup.h +++ b/Python/crossinterp_data_lookup.h @@ -440,7 +440,8 @@ _none_shared(PyThreadState *tstate, PyObject *obj, static PyObject * _new_notimplemented_object(_PyCrossInterpreterData *data) { - return Py_NewRef(Py_NotImplemented); + assert(_Py_IsImmortal(Py_NotImplemented)); + return Py_NotImplemented; } static int From c53c196d9824b8fb37d79861ceeefe5d423584d2 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 9 Feb 2025 18:19:13 +0300 Subject: [PATCH 4/4] Rename NEWS --- .../2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/{Core and Builtins => Core_and_Builtins}/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst (100%) diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst similarity index 100% rename from Misc/NEWS.d/next/Core and Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst rename to Misc/NEWS.d/next/Core_and_Builtins/2024-05-12-15-19-40.gh-issue-118965.Lr3qAz.rst