From 3b329c684aa924f539f29486723dbb490e03ed83 Mon Sep 17 00:00:00 2001 From: Brett Simmers Date: Tue, 28 Mar 2023 12:27:28 -0700 Subject: [PATCH 1/3] gh-103091: Add PyType_AssignVersionTag --- Doc/c-api/type.rst | 9 +++++++++ Include/object.h | 9 +++++++++ Lib/test/test_type_cache.py | 15 ++++++++++++++- ...2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst | 1 + Modules/_testcapimodule.c | 13 +++++++++++++ Objects/typeobject.c | 4 ++++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 7b5d1fac40ed87..5a8ff5295c3fe0 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -232,6 +232,15 @@ Type Objects .. versionadded:: 3.11 +.. c:function:: int PyType_AssignVersionTag(PyTypeObject *type) + + Attempt to assign a version tag to the given type. + + Returns 1 if the type already had a valid version tag or a new one was + assigned, or 0 if a new tag could not be assigned. + + .. versionadded:: 3.12 + Creating Heap-Allocated Types ............................. diff --git a/Include/object.h b/Include/object.h index 2943a6066818cd..ea983e4e4aae30 100644 --- a/Include/object.h +++ b/Include/object.h @@ -861,6 +861,15 @@ static inline int PyType_CheckExact(PyObject *op) { # define PyType_CheckExact(op) PyType_CheckExact(_PyObject_CAST(op)) #endif +#if !defined(Py_LIMITED_API) +/* Attempt to assign a version tag to the given type. + * + * Returns 1 if the type already had a valid version tag or a new one was + * assigned, or 0 if a new tag could not be assigned. + */ +PyAPI_FUNC(int) PyType_AssignVersionTag(PyTypeObject *type); +#endif + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_type_cache.py b/Lib/test/test_type_cache.py index 8502f6b0584b00..0ca82cc2fb0a62 100644 --- a/Lib/test/test_type_cache.py +++ b/Lib/test/test_type_cache.py @@ -9,7 +9,7 @@ # Skip this test if the _testcapi module isn't available. type_get_version = import_helper.import_module('_testcapi').type_get_version - +type_assign_version = import_helper.import_module('_testcapi').type_assign_version @support.cpython_only @unittest.skipIf(_clear_type_cache is None, "requires sys._clear_type_cache") @@ -42,6 +42,19 @@ def test_tp_version_tag_unique(self): self.assertEqual(len(set(all_version_tags)), 30, msg=f"{all_version_tags} contains non-unique versions") + def test_type_assign_version(self): + class C: + x = 5 + + self.assertEqual(type_assign_version(C), 1) + c_ver = type_get_version(C) + + C.x = 6 + self.assertEqual(type_get_version(C), 0) + self.assertEqual(type_assign_version(C), 1) + self.assertNotEqual(type_get_version(C), 0) + self.assertNotEqual(type_get_version(C), c_ver) + if __name__ == "__main__": support.run_unittest(TypeCacheTests) diff --git a/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst b/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst new file mode 100644 index 00000000000000..fd746ccc02c6ef --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst @@ -0,0 +1 @@ +Add a new C-API function to eagerly assign a version tag to a PyTypeObject: ``PyType_AssignVersionTag()``. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 3d9a2aeeb7cfd5..183354adc67a88 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2733,6 +2733,18 @@ type_get_version(PyObject *self, PyObject *type) } +static PyObject * +type_assign_version(PyObject *self, PyObject *type) +{ + if (!PyType_Check(type)) { + PyErr_SetString(PyExc_TypeError, "argument must be a type"); + return NULL; + } + int res = PyType_AssignVersionTag((PyTypeObject *)type); + return PyLong_FromLong(res); +} + + // Test PyThreadState C API static PyObject * test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) @@ -3499,6 +3511,7 @@ static PyMethodDef TestMethods[] = { {"test_py_is_macros", test_py_is_macros, METH_NOARGS}, {"test_py_is_funcs", test_py_is_funcs, METH_NOARGS}, {"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")}, + {"type_assign_version", type_assign_version, METH_O, PyDoc_STR("PyType_AssignVersionTag")}, {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, {"frame_getlocals", frame_getlocals, METH_O, NULL}, {"frame_getglobals", frame_getglobals, METH_O, NULL}, diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 69e84743f13aac..b3564e08be9363 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -598,6 +598,10 @@ assign_version_tag(PyTypeObject *type) return 1; } +int PyType_AssignVersionTag(PyTypeObject *type) +{ + return assign_version_tag(type); +} static PyMemberDef type_members[] = { {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, From 840f6c9b508fa1a6eaf12991ed4f606108de1ac4 Mon Sep 17 00:00:00 2001 From: Brett Simmers Date: Fri, 31 Mar 2023 11:17:39 -0700 Subject: [PATCH 2/3] Rename to PyUnstable_AssignVersionTag, move to Include/cptyhon/object.h, fix some newlines --- Doc/c-api/type.rst | 2 +- Include/cpython/object.h | 7 +++++++ Include/object.h | 9 --------- Lib/test/test_type_cache.py | 1 + .../C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst | 2 +- Modules/_testcapimodule.c | 4 ++-- Objects/typeobject.c | 3 ++- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 5a8ff5295c3fe0..832dd346a36193 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -232,7 +232,7 @@ Type Objects .. versionadded:: 3.11 -.. c:function:: int PyType_AssignVersionTag(PyTypeObject *type) +.. c:function:: int PyUnstable_AssignVersionTag(PyTypeObject *type) Attempt to assign a version tag to the given type. diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 859ffb91e223dc..419e20a838b7bd 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -553,3 +553,10 @@ PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback); PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id); PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type); PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type); + +/* Attempt to assign a version tag to the given type. + * + * Returns 1 if the type already had a valid version tag or a new one was + * assigned, or 0 if a new tag could not be assigned. + */ +PyAPI_FUNC(int) PyUnstable_AssignVersionTag(PyTypeObject *type); diff --git a/Include/object.h b/Include/object.h index ea983e4e4aae30..2943a6066818cd 100644 --- a/Include/object.h +++ b/Include/object.h @@ -861,15 +861,6 @@ static inline int PyType_CheckExact(PyObject *op) { # define PyType_CheckExact(op) PyType_CheckExact(_PyObject_CAST(op)) #endif -#if !defined(Py_LIMITED_API) -/* Attempt to assign a version tag to the given type. - * - * Returns 1 if the type already had a valid version tag or a new one was - * assigned, or 0 if a new tag could not be assigned. - */ -PyAPI_FUNC(int) PyType_AssignVersionTag(PyTypeObject *type); -#endif - #ifdef __cplusplus } #endif diff --git a/Lib/test/test_type_cache.py b/Lib/test/test_type_cache.py index 0ca82cc2fb0a62..24f83cd3e172c7 100644 --- a/Lib/test/test_type_cache.py +++ b/Lib/test/test_type_cache.py @@ -11,6 +11,7 @@ type_get_version = import_helper.import_module('_testcapi').type_get_version type_assign_version = import_helper.import_module('_testcapi').type_assign_version + @support.cpython_only @unittest.skipIf(_clear_type_cache is None, "requires sys._clear_type_cache") class TypeCacheTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst b/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst index fd746ccc02c6ef..2669acfbd4e965 100644 --- a/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst +++ b/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst @@ -1 +1 @@ -Add a new C-API function to eagerly assign a version tag to a PyTypeObject: ``PyType_AssignVersionTag()``. +Add a new C-API function to eagerly assign a version tag to a PyTypeObject: ``PyUnstable_AssignVersionTag()``. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 183354adc67a88..efc7542b980b0b 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2740,7 +2740,7 @@ type_assign_version(PyObject *self, PyObject *type) PyErr_SetString(PyExc_TypeError, "argument must be a type"); return NULL; } - int res = PyType_AssignVersionTag((PyTypeObject *)type); + int res = PyUnstable_AssignVersionTag((PyTypeObject *)type); return PyLong_FromLong(res); } @@ -3511,7 +3511,7 @@ static PyMethodDef TestMethods[] = { {"test_py_is_macros", test_py_is_macros, METH_NOARGS}, {"test_py_is_funcs", test_py_is_funcs, METH_NOARGS}, {"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")}, - {"type_assign_version", type_assign_version, METH_O, PyDoc_STR("PyType_AssignVersionTag")}, + {"type_assign_version", type_assign_version, METH_O, PyDoc_STR("PyUnstable_AssignVersionTag")}, {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, {"frame_getlocals", frame_getlocals, METH_O, NULL}, {"frame_getglobals", frame_getglobals, METH_O, NULL}, diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b3564e08be9363..3067f2da83096d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -598,11 +598,12 @@ assign_version_tag(PyTypeObject *type) return 1; } -int PyType_AssignVersionTag(PyTypeObject *type) +int PyUnstable_AssignVersionTag(PyTypeObject *type) { return assign_version_tag(type); } + static PyMemberDef type_members[] = { {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY}, From b8383404821972d2bd5020578429686062930b3f Mon Sep 17 00:00:00 2001 From: Brett Simmers Date: Thu, 20 Apr 2023 09:06:19 -0700 Subject: [PATCH 3/3] Rename to PyUnstable_Type_AssignVersionTag --- Doc/c-api/type.rst | 2 +- Include/cpython/object.h | 2 +- .../next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst | 2 +- Modules/_testcapimodule.c | 4 ++-- Objects/typeobject.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 832dd346a36193..69b15296993301 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -232,7 +232,7 @@ Type Objects .. versionadded:: 3.11 -.. c:function:: int PyUnstable_AssignVersionTag(PyTypeObject *type) +.. c:function:: int PyUnstable_Type_AssignVersionTag(PyTypeObject *type) Attempt to assign a version tag to the given type. diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 419e20a838b7bd..ddfd77298e4c2e 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -559,4 +559,4 @@ PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type); * Returns 1 if the type already had a valid version tag or a new one was * assigned, or 0 if a new tag could not be assigned. */ -PyAPI_FUNC(int) PyUnstable_AssignVersionTag(PyTypeObject *type); +PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type); diff --git a/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst b/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst index 2669acfbd4e965..28c77b6816af87 100644 --- a/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst +++ b/Misc/NEWS.d/next/C API/2023-03-28-12-31-51.gh-issue-103091.CzZyaZ.rst @@ -1 +1 @@ -Add a new C-API function to eagerly assign a version tag to a PyTypeObject: ``PyUnstable_AssignVersionTag()``. +Add a new C-API function to eagerly assign a version tag to a PyTypeObject: ``PyUnstable_Type_AssignVersionTag()``. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index efc7542b980b0b..58de4682e894a2 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2740,7 +2740,7 @@ type_assign_version(PyObject *self, PyObject *type) PyErr_SetString(PyExc_TypeError, "argument must be a type"); return NULL; } - int res = PyUnstable_AssignVersionTag((PyTypeObject *)type); + int res = PyUnstable_Type_AssignVersionTag((PyTypeObject *)type); return PyLong_FromLong(res); } @@ -3511,7 +3511,7 @@ static PyMethodDef TestMethods[] = { {"test_py_is_macros", test_py_is_macros, METH_NOARGS}, {"test_py_is_funcs", test_py_is_funcs, METH_NOARGS}, {"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")}, - {"type_assign_version", type_assign_version, METH_O, PyDoc_STR("PyUnstable_AssignVersionTag")}, + {"type_assign_version", type_assign_version, METH_O, PyDoc_STR("PyUnstable_Type_AssignVersionTag")}, {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, {"frame_getlocals", frame_getlocals, METH_O, NULL}, {"frame_getglobals", frame_getglobals, METH_O, NULL}, diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 3067f2da83096d..7c83fc2988b639 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -598,7 +598,7 @@ assign_version_tag(PyTypeObject *type) return 1; } -int PyUnstable_AssignVersionTag(PyTypeObject *type) +int PyUnstable_Type_AssignVersionTag(PyTypeObject *type) { return assign_version_tag(type); } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy