[Python-checkins] gh-121615: Improve `module.rst` C-API docs with better error descriptions (#121616)
https://github.com/python/cpython/commit/e6264b44dc7221c713b14dfa0f5929b33d362829 commit: e6264b44dc7221c713b14dfa0f5929b33d362829 branch: main author: sobolevn committer: sobolevn date: 2024-07-11T11:57:22+03:00 summary: gh-121615: Improve `module.rst` C-API docs with better error descriptions (#121616) files: M Doc/c-api/module.rst diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 63e3bed6727987..ce9d5a0f758b29 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -43,6 +43,8 @@ Module Objects to ``None``); the caller is responsible for providing a :attr:`__file__` attribute. + Return ``NULL`` with an exception set on error. + .. versionadded:: 3.3 .. versionchanged:: 3.4 @@ -265,6 +267,8 @@ of the following two module creation functions: API version *module_api_version*. If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. + Return ``NULL`` with an exception set on error. + .. note:: Most uses of this function should be using :c:func:`PyModule_Create` @@ -461,6 +465,8 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. + Return ``NULL`` with an exception set on error. + .. note:: Most uses of this function should be using :c:func:`PyModule_FromDefAndSpec` @@ -601,15 +607,16 @@ state: .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) Add an integer constant to *module* as *name*. This convenience function can be - used from the module's initialization function. Return ``-1`` on error, ``0`` on - success. + used from the module's initialization function. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value) Add a string constant to *module* as *name*. This convenience function can be used from the module's initialization function. The string *value* must be - ``NULL``-terminated. Return ``-1`` on error, ``0`` on success. + ``NULL``-terminated. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:macro:: PyModule_AddIntMacro(module, macro) @@ -617,7 +624,7 @@ state: Add an int constant to *module*. The name and the value are taken from *macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int constant *AF_INET* with the value of *AF_INET* to *module*. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:macro:: PyModule_AddStringMacro(module, macro) @@ -630,7 +637,7 @@ state: The type object is finalized by calling internally :c:func:`PyType_Ready`. The name of the type object is taken from the last component of :c:member:`~PyTypeObject.tp_name` after dot. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.9 @@ -643,7 +650,7 @@ state: import machinery assumes the module does not support running without the GIL. This function is only available in Python builds configured with :option:`--disable-gil`. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.13 @@ -682,14 +689,14 @@ since multiple such modules can be created from a single definition. The caller must hold the GIL. - Return 0 on success or -1 on failure. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.3 .. c:function:: int PyState_RemoveModule(PyModuleDef *def) Removes the module object created from *def* from the interpreter state. - Return 0 on success or -1 on failure. + Return ``-1`` with an exception set on error, ``0`` on success. The caller must hold the GIL. ___ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: [email protected]
[Python-checkins] [3.12] gh-121615: Improve `module.rst` C-API docs with better error descriptions (GH-121616) (#121619)
https://github.com/python/cpython/commit/5492f84c14bc0c93a24863349b6c998bdb18e93f commit: 5492f84c14bc0c93a24863349b6c998bdb18e93f branch: 3.12 author: sobolevn committer: sobolevn date: 2024-07-11T09:12:06Z summary: [3.12] gh-121615: Improve `module.rst` C-API docs with better error descriptions (GH-121616) (#121619) (cherry picked from commit e6264b44dc7221c713b14dfa0f5929b33d362829) files: M Doc/c-api/module.rst diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index f941f0c7d42b2b..02efb9921a9b99 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -43,6 +43,8 @@ Module Objects to ``None``); the caller is responsible for providing a :attr:`__file__` attribute. + Return ``NULL`` with an exception set on error. + .. versionadded:: 3.3 .. versionchanged:: 3.4 @@ -265,6 +267,8 @@ of the following two module creation functions: API version *module_api_version*. If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. + Return ``NULL`` with an exception set on error. + .. note:: Most uses of this function should be using :c:func:`PyModule_Create` @@ -436,6 +440,8 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. + Return ``NULL`` with an exception set on error. + .. note:: Most uses of this function should be using :c:func:`PyModule_FromDefAndSpec` @@ -579,15 +585,16 @@ state: .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) Add an integer constant to *module* as *name*. This convenience function can be - used from the module's initialization function. Return ``-1`` on error, ``0`` on - success. + used from the module's initialization function. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value) Add a string constant to *module* as *name*. This convenience function can be used from the module's initialization function. The string *value* must be - ``NULL``-terminated. Return ``-1`` on error, ``0`` on success. + ``NULL``-terminated. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:macro:: PyModule_AddIntMacro(module, macro) @@ -595,7 +602,7 @@ state: Add an int constant to *module*. The name and the value are taken from *macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int constant *AF_INET* with the value of *AF_INET* to *module*. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:macro:: PyModule_AddStringMacro(module, macro) @@ -608,7 +615,7 @@ state: The type object is finalized by calling internally :c:func:`PyType_Ready`. The name of the type object is taken from the last component of :c:member:`~PyTypeObject.tp_name` after dot. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.9 @@ -647,14 +654,14 @@ since multiple such modules can be created from a single definition. The caller must hold the GIL. - Return 0 on success or -1 on failure. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.3 .. c:function:: int PyState_RemoveModule(PyModuleDef *def) Removes the module object created from *def* from the interpreter state. - Return 0 on success or -1 on failure. + Return ``-1`` with an exception set on error, ``0`` on success. The caller must hold the GIL. ___ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: [email protected]
[Python-checkins] [3.13] gh-121615: Improve `module.rst` C-API docs with better error descriptions (GH-121616) (#121618)
https://github.com/python/cpython/commit/261c8e9d476653a48c775f4b1820c0554bae232a commit: 261c8e9d476653a48c775f4b1820c0554bae232a branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: sobolevn date: 2024-07-11T09:15:18Z summary: [3.13] gh-121615: Improve `module.rst` C-API docs with better error descriptions (GH-121616) (#121618) gh-121615: Improve `module.rst` C-API docs with better error descriptions (GH-121616) (cherry picked from commit e6264b44dc7221c713b14dfa0f5929b33d362829) Co-authored-by: sobolevn files: M Doc/c-api/module.rst diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 63e3bed6727987..ce9d5a0f758b29 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -43,6 +43,8 @@ Module Objects to ``None``); the caller is responsible for providing a :attr:`__file__` attribute. + Return ``NULL`` with an exception set on error. + .. versionadded:: 3.3 .. versionchanged:: 3.4 @@ -265,6 +267,8 @@ of the following two module creation functions: API version *module_api_version*. If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. + Return ``NULL`` with an exception set on error. + .. note:: Most uses of this function should be using :c:func:`PyModule_Create` @@ -461,6 +465,8 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. + Return ``NULL`` with an exception set on error. + .. note:: Most uses of this function should be using :c:func:`PyModule_FromDefAndSpec` @@ -601,15 +607,16 @@ state: .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) Add an integer constant to *module* as *name*. This convenience function can be - used from the module's initialization function. Return ``-1`` on error, ``0`` on - success. + used from the module's initialization function. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value) Add a string constant to *module* as *name*. This convenience function can be used from the module's initialization function. The string *value* must be - ``NULL``-terminated. Return ``-1`` on error, ``0`` on success. + ``NULL``-terminated. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:macro:: PyModule_AddIntMacro(module, macro) @@ -617,7 +624,7 @@ state: Add an int constant to *module*. The name and the value are taken from *macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int constant *AF_INET* with the value of *AF_INET* to *module*. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. c:macro:: PyModule_AddStringMacro(module, macro) @@ -630,7 +637,7 @@ state: The type object is finalized by calling internally :c:func:`PyType_Ready`. The name of the type object is taken from the last component of :c:member:`~PyTypeObject.tp_name` after dot. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.9 @@ -643,7 +650,7 @@ state: import machinery assumes the module does not support running without the GIL. This function is only available in Python builds configured with :option:`--disable-gil`. - Return ``-1`` on error, ``0`` on success. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.13 @@ -682,14 +689,14 @@ since multiple such modules can be created from a single definition. The caller must hold the GIL. - Return 0 on success or -1 on failure. + Return ``-1`` with an exception set on error, ``0`` on success. .. versionadded:: 3.3 .. c:function:: int PyState_RemoveModule(PyModuleDef *def) Removes the module object created from *def* from the interpreter state. - Return 0 on success or -1 on failure. + Return ``-1`` with an exception set on error, ``0`` on success. The caller must hold the GIL. ___ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: [email protected]
[Python-checkins] gh-121592: Make select.poll() and related objects thread-safe (#121594)
https://github.com/python/cpython/commit/44937d11a6a045a624918db78aa36e715ffabcd4
commit: 44937d11a6a045a624918db78aa36e715ffabcd4
branch: main
author: Sam Gross
committer: colesbury
date: 2024-07-11T10:21:09-04:00
summary:
gh-121592: Make select.poll() and related objects thread-safe (#121594)
This makes select.poll() and kqueue() objects thread-safe in the
free-threaded build. Note that calling close() concurrently with other
functions is still not thread-safe due to races on file descriptors
(gh-121544).
files:
M Modules/clinic/selectmodule.c.h
M Modules/selectmodule.c
diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h
index dc7d3fb814396d..0ccbf63b688f1b 100644
--- a/Modules/clinic/selectmodule.c.h
+++ b/Modules/clinic/selectmodule.c.h
@@ -6,6 +6,7 @@ preserve
# include "pycore_gc.h" // PyGC_Head
# include "pycore_runtime.h" // _Py_ID()
#endif
+#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
#include "pycore_long.h" // _PyLong_UnsignedShort_Converter()
#include "pycore_modsupport.h"// _PyArg_CheckPositional()
@@ -110,7 +111,9 @@ select_poll_register(pollObject *self, PyObject *const
*args, Py_ssize_t nargs)
goto exit;
}
skip_optional:
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_poll_register_impl(self, fd, eventmask);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -155,7 +158,9 @@ select_poll_modify(pollObject *self, PyObject *const *args,
Py_ssize_t nargs)
if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) {
goto exit;
}
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_poll_modify_impl(self, fd, eventmask);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -187,7 +192,9 @@ select_poll_unregister(pollObject *self, PyObject *arg)
if (fd < 0) {
goto exit;
}
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_poll_unregister_impl(self, fd);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -230,7 +237,9 @@ select_poll_poll(pollObject *self, PyObject *const *args,
Py_ssize_t nargs)
}
timeout_obj = args[0];
skip_optional:
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_poll_poll_impl(self, timeout_obj);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -281,7 +290,9 @@ select_devpoll_register(devpollObject *self, PyObject
*const *args, Py_ssize_t n
goto exit;
}
skip_optional:
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_devpoll_register_impl(self, fd, eventmask);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -332,7 +343,9 @@ select_devpoll_modify(devpollObject *self, PyObject *const
*args, Py_ssize_t nar
goto exit;
}
skip_optional:
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_devpoll_modify_impl(self, fd, eventmask);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -364,7 +377,9 @@ select_devpoll_unregister(devpollObject *self, PyObject
*arg)
if (fd < 0) {
goto exit;
}
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_devpoll_unregister_impl(self, fd);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -407,7 +422,9 @@ select_devpoll_poll(devpollObject *self, PyObject *const
*args, Py_ssize_t nargs
}
timeout_obj = args[0];
skip_optional:
+Py_BEGIN_CRITICAL_SECTION(self);
return_value = select_devpoll_poll_impl(self, timeout_obj);
+Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -434,7 +451,13 @@ select_devpoll_close_impl(devpollObject *self);
static PyObject *
select_devpoll_close(devpollObject *self, PyObject *Py_UNUSED(ignored))
{
-return select_devpoll_close_impl(self);
+PyObject *return_value = NULL;
+
+Py_BEGIN_CRITICAL_SECTION(self);
+return_value = select_devpoll_close_impl(self);
+Py_END_CRITICAL_SECTION();
+
+return return_value;
}
#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) &&
defined(HAVE_SYS_DEVPOLL_H) */
@@ -456,7 +479,13 @@ select_devpoll_fileno_impl(devpollObject *self);
static PyObject *
select_devpoll_fileno(devpollObject *self, PyObject *Py_UNUSED(ignored))
{
-return select_devpoll_fileno_impl(self);
+PyObject *return_value = NULL;
+
+Py_BEGIN_CRITICAL_SECTION(self);
+return_value = select_devpoll_fileno_impl(self);
+Py_END_CRITICAL_SECTION();
+
+return return_value;
}
#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) &&
defined(HAVE_SYS_DEVPOLL_H) */
@@ -615,7 +644,13 @@ select_epoll_close_impl(pyEpoll_Object *self);
static PyObject *
select_epoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored))
{
-return select_epoll_close_impl(self);
+PyObject *return_value = NULL;
+
+Py_BEGIN_CRITICAL_SECTION(self);
+return_value = select_epoll_close_impl(self);
+P
[Python-checkins] gh-121332: Make AST node constructor check _attributes instead of hardcoding attributes (#121334)
https://github.com/python/cpython/commit/58e8cf2bb61f82df9eabd1209fe5e3d146e4c8cd
commit: 58e8cf2bb61f82df9eabd1209fe5e3d146e4c8cd
branch: main
author: Jelle Zijlstra
committer: JelleZijlstra
date: 2024-07-11T14:34:53Z
summary:
gh-121332: Make AST node constructor check _attributes instead of hardcoding
attributes (#121334)
files:
A Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
M Lib/test/test_ast.py
M Parser/asdl_c.py
M Python/Python-ast.c
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index eb3aefd5c262f6..497c3f261a1fca 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -1386,15 +1386,7 @@ class MyNode(ast.AST):
self.assertEqual(node.y, 1)
y = object()
-# custom attributes are currently not supported and raise a warning
-# because the allowed attributes are hard-coded !
-msg = (
-"MyNode.__init__ got an unexpected keyword argument 'y'. "
-"Support for arbitrary keyword arguments is deprecated and "
-"will be removed in Python 3.15"
-)
-with self.assertWarnsRegex(DeprecationWarning, re.escape(msg)):
-repl = copy.replace(node, y=y)
+repl = copy.replace(node, y=y)
# assert that there is no side-effect
self.assertEqual(node.x, 0)
self.assertEqual(node.y, 1)
@@ -3250,6 +3242,18 @@ class FieldsAndTypes(ast.AST):
obj = FieldsAndTypes(a=1)
self.assertEqual(obj.a, 1)
+def test_custom_attributes(self):
+class MyAttrs(ast.AST):
+_attributes = ("a", "b")
+
+obj = MyAttrs(a=1, b=2)
+self.assertEqual(obj.a, 1)
+self.assertEqual(obj.b, 2)
+
+with self.assertWarnsRegex(DeprecationWarning,
+ r"MyAttrs.__init__ got an unexpected
keyword argument 'c'."):
+obj = MyAttrs(c=3)
+
def test_fields_and_types_no_default(self):
class FieldsAndTypesNoDefault(ast.AST):
_fields = ('a',)
diff --git
a/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
b/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
new file mode 100644
index 00..480f27e05953a6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
@@ -0,0 +1,4 @@
+Fix constructor of :mod:`ast` nodes with custom ``_attributes``. Previously,
+passing custom attributes would raise a :py:exc:`DeprecationWarning`. Passing
+arguments to the constructor that are not in ``_fields`` or ``_attributes``
+remains deprecated. Patch by Jelle Zijlstra.
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index f3667801782f2b..e6867f138a5ccb 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -880,7 +880,7 @@ def visitModule(self, mod):
Py_ssize_t i, numfields = 0;
int res = -1;
-PyObject *key, *value, *fields, *remaining_fields = NULL;
+PyObject *key, *value, *fields, *attributes = NULL, *remaining_fields =
NULL;
if (PyObject_GetOptionalAttr((PyObject*)Py_TYPE(self), state->_fields,
&fields) < 0) {
goto cleanup;
}
@@ -947,22 +947,32 @@ def visitModule(self, mod):
goto cleanup;
}
}
-else if (
-PyUnicode_CompareWithASCIIString(key, "lineno") != 0 &&
-PyUnicode_CompareWithASCIIString(key, "col_offset") != 0 &&
-PyUnicode_CompareWithASCIIString(key, "end_lineno") != 0 &&
-PyUnicode_CompareWithASCIIString(key, "end_col_offset") != 0
-) {
-if (PyErr_WarnFormat(
-PyExc_DeprecationWarning, 1,
-"%.400s.__init__ got an unexpected keyword argument '%U'. "
-"Support for arbitrary keyword arguments is deprecated "
-"and will be removed in Python 3.15.",
-Py_TYPE(self)->tp_name, key
-) < 0) {
+else {
+// Lazily initialize "attributes"
+if (attributes == NULL) {
+attributes = PyObject_GetAttr((PyObject*)Py_TYPE(self),
state->_attributes);
+if (attributes == NULL) {
+res = -1;
+goto cleanup;
+}
+}
+int contains = PySequence_Contains(attributes, key);
+if (contains == -1) {
res = -1;
goto cleanup;
}
+else if (contains == 0) {
+if (PyErr_WarnFormat(
+PyExc_DeprecationWarning, 1,
+"%.400s.__init__ got an unexpected keyword argument
'%U'. "
+"Support for arbitrary keyword arguments is deprecated
"
+"and will be removed in Python 3.15.",
+Py_TYPE(self)->tp_name, key
+
[Python-checkins] [3.13] gh-121592: Make select.poll() and related objects thread-safe (GH-121594) (#121623)
https://github.com/python/cpython/commit/3b5f8d256c534e9b2baa64ec151da0d590213667 commit: 3b5f8d256c534e9b2baa64ec151da0d590213667 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: colesbury date: 2024-07-11T14:44:54Z summary: [3.13] gh-121592: Make select.poll() and related objects thread-safe (GH-121594) (#121623) This makes select.poll() and kqueue() objects thread-safe in the free-threaded build. Note that calling close() concurrently with other functions is still not thread-safe due to races on file descriptors (gh-121544). (cherry picked from commit 44937d11a6a045a624918db78aa36e715ffabcd4) Co-authored-by: Sam Gross files: M Modules/clinic/selectmodule.c.h M Modules/selectmodule.c diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index dc7d3fb814396d..0ccbf63b688f1b 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() #include "pycore_long.h" // _PyLong_UnsignedShort_Converter() #include "pycore_modsupport.h"// _PyArg_CheckPositional() @@ -110,7 +111,9 @@ select_poll_register(pollObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_poll_register_impl(self, fd, eventmask); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -155,7 +158,9 @@ select_poll_modify(pollObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) { goto exit; } +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_poll_modify_impl(self, fd, eventmask); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -187,7 +192,9 @@ select_poll_unregister(pollObject *self, PyObject *arg) if (fd < 0) { goto exit; } +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_poll_unregister_impl(self, fd); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -230,7 +237,9 @@ select_poll_poll(pollObject *self, PyObject *const *args, Py_ssize_t nargs) } timeout_obj = args[0]; skip_optional: +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_poll_poll_impl(self, timeout_obj); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -281,7 +290,9 @@ select_devpoll_register(devpollObject *self, PyObject *const *args, Py_ssize_t n goto exit; } skip_optional: +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_devpoll_register_impl(self, fd, eventmask); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -332,7 +343,9 @@ select_devpoll_modify(devpollObject *self, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_devpoll_modify_impl(self, fd, eventmask); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -364,7 +377,9 @@ select_devpoll_unregister(devpollObject *self, PyObject *arg) if (fd < 0) { goto exit; } +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_devpoll_unregister_impl(self, fd); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -407,7 +422,9 @@ select_devpoll_poll(devpollObject *self, PyObject *const *args, Py_ssize_t nargs } timeout_obj = args[0]; skip_optional: +Py_BEGIN_CRITICAL_SECTION(self); return_value = select_devpoll_poll_impl(self, timeout_obj); +Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -434,7 +451,13 @@ select_devpoll_close_impl(devpollObject *self); static PyObject * select_devpoll_close(devpollObject *self, PyObject *Py_UNUSED(ignored)) { -return select_devpoll_close_impl(self); +PyObject *return_value = NULL; + +Py_BEGIN_CRITICAL_SECTION(self); +return_value = select_devpoll_close_impl(self); +Py_END_CRITICAL_SECTION(); + +return return_value; } #endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ @@ -456,7 +479,13 @@ select_devpoll_fileno_impl(devpollObject *self); static PyObject * select_devpoll_fileno(devpollObject *self, PyObject *Py_UNUSED(ignored)) { -return select_devpoll_fileno_impl(self); +PyObject *return_value = NULL; + +Py_BEGIN_CRITICAL_SECTION(self); +return_value = select_devpoll_fileno_impl(self); +Py_END_CRITICAL_SECTION(); + +return return_value; } #endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ @@ -615,7 +644,13 @@ select_epoll_close_impl(pyEpoll_Object *self); static PyObject * select_epoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) { -
[Python-checkins] [3.13] gh-121332: Make AST node constructor check _attributes instead of hardcoding attributes (GH-121334) (#121625)
https://github.com/python/cpython/commit/38c4028dd9aeeeb1fe4ba1444307e3f06fc63aa0
commit: 38c4028dd9aeeeb1fe4ba1444307e3f06fc63aa0
branch: 3.13
author: Jelle Zijlstra
committer: JelleZijlstra
date: 2024-07-11T15:51:32Z
summary:
[3.13] gh-121332: Make AST node constructor check _attributes instead of
hardcoding attributes (GH-121334) (#121625)
(cherry picked from commit 58e8cf2bb61f82df9eabd1209fe5e3d146e4c8cd)
files:
A Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
M Lib/test/test_ast.py
M Parser/asdl_c.py
M Python/Python-ast.c
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index 93bd5dec6eac74..744cd238ea1407 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -3148,6 +3148,18 @@ class FieldsAndTypes(ast.AST):
obj = FieldsAndTypes(a=1)
self.assertEqual(obj.a, 1)
+def test_custom_attributes(self):
+class MyAttrs(ast.AST):
+_attributes = ("a", "b")
+
+obj = MyAttrs(a=1, b=2)
+self.assertEqual(obj.a, 1)
+self.assertEqual(obj.b, 2)
+
+with self.assertWarnsRegex(DeprecationWarning,
+ r"MyAttrs.__init__ got an unexpected
keyword argument 'c'."):
+obj = MyAttrs(c=3)
+
def test_fields_and_types_no_default(self):
class FieldsAndTypesNoDefault(ast.AST):
_fields = ('a',)
diff --git
a/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
b/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
new file mode 100644
index 00..480f27e05953a6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-07-03-07-25-21.gh-issue-121332.Iz6FEq.rst
@@ -0,0 +1,4 @@
+Fix constructor of :mod:`ast` nodes with custom ``_attributes``. Previously,
+passing custom attributes would raise a :py:exc:`DeprecationWarning`. Passing
+arguments to the constructor that are not in ``_fields`` or ``_attributes``
+remains deprecated. Patch by Jelle Zijlstra.
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index e338656a5b1eb9..3711cf1280f7bf 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -880,7 +880,7 @@ def visitModule(self, mod):
Py_ssize_t i, numfields = 0;
int res = -1;
-PyObject *key, *value, *fields, *remaining_fields = NULL;
+PyObject *key, *value, *fields, *attributes = NULL, *remaining_fields =
NULL;
if (PyObject_GetOptionalAttr((PyObject*)Py_TYPE(self), state->_fields,
&fields) < 0) {
goto cleanup;
}
@@ -947,22 +947,32 @@ def visitModule(self, mod):
goto cleanup;
}
}
-else if (
-PyUnicode_CompareWithASCIIString(key, "lineno") != 0 &&
-PyUnicode_CompareWithASCIIString(key, "col_offset") != 0 &&
-PyUnicode_CompareWithASCIIString(key, "end_lineno") != 0 &&
-PyUnicode_CompareWithASCIIString(key, "end_col_offset") != 0
-) {
-if (PyErr_WarnFormat(
-PyExc_DeprecationWarning, 1,
-"%.400s.__init__ got an unexpected keyword argument '%U'. "
-"Support for arbitrary keyword arguments is deprecated "
-"and will be removed in Python 3.15.",
-Py_TYPE(self)->tp_name, key
-) < 0) {
+else {
+// Lazily initialize "attributes"
+if (attributes == NULL) {
+attributes = PyObject_GetAttr((PyObject*)Py_TYPE(self),
state->_attributes);
+if (attributes == NULL) {
+res = -1;
+goto cleanup;
+}
+}
+int contains = PySequence_Contains(attributes, key);
+if (contains == -1) {
res = -1;
goto cleanup;
}
+else if (contains == 0) {
+if (PyErr_WarnFormat(
+PyExc_DeprecationWarning, 1,
+"%.400s.__init__ got an unexpected keyword argument
'%U'. "
+"Support for arbitrary keyword arguments is deprecated
"
+"and will be removed in Python 3.15.",
+Py_TYPE(self)->tp_name, key
+) < 0) {
+res = -1;
+goto cleanup;
+}
+}
}
res = PyObject_SetAttr(self, key, value);
if (res < 0) {
@@ -1045,6 +1055,7 @@ def visitModule(self, mod):
Py_DECREF(field_types);
}
cleanup:
+Py_XDECREF(attributes);
Py_XDECREF(fields);
Py_XDECREF(remaining_fields);
return res;
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 01ffea1869350b..e38a145271589a 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -5079,7 +5079,7 @@ ast_type_init(PyObject *self
[Python-checkins] gh-117482: Fix Builtin Types Slot Wrappers (gh-121602)
https://github.com/python/cpython/commit/5250a031332eb9499d5fc190d7287642e5a144b9
commit: 5250a031332eb9499d5fc190d7287642e5a144b9
branch: main
author: Eric Snow
committer: ericsnowcurrently
date: 2024-07-11T20:20:14Z
summary:
gh-117482: Fix Builtin Types Slot Wrappers (gh-121602)
When builtin static types are initialized for a subinterpreter, various "tp"
slots have already been inherited (for the main interpreter). This was
interfering with the logic in add_operators() (in Objects/typeobject.c),
causing a wrapper to get created when it shouldn't. This change fixes that by
preserving the original data from the static type struct and checking that.
files:
A Misc/NEWS.d/next/Core and
Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst
M Include/internal/pycore_typeobject.h
M Lib/test/test_types.py
M Objects/typeobject.c
diff --git a/Include/internal/pycore_typeobject.h
b/Include/internal/pycore_typeobject.h
index 32bd19d968b917..df6bfef715dd34 100644
--- a/Include/internal/pycore_typeobject.h
+++ b/Include/internal/pycore_typeobject.h
@@ -33,6 +33,7 @@ struct _types_runtime_state {
struct {
struct {
PyTypeObject *type;
+PyTypeObject def;
int64_t interp_count;
} types[_Py_MAX_MANAGED_STATIC_TYPES];
} managed_static;
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index fbca198aab5180..38a98828085e2f 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -10,6 +10,7 @@
import pickle
import locale
import sys
+import textwrap
import types
import unittest.mock
import weakref
@@ -2345,5 +2346,40 @@ def ex(a, /, b, *, c):
)
+class SubinterpreterTests(unittest.TestCase):
+
+@classmethod
+def setUpClass(cls):
+global interpreters
+try:
+from test.support import interpreters
+except ModuleNotFoundError:
+raise unittest.SkipTest('subinterpreters required')
+import test.support.interpreters.channels
+
+@cpython_only
+def test_slot_wrappers(self):
+rch, sch = interpreters.channels.create()
+
+# For now it's sufficient to check int.__str__.
+# See https://github.com/python/cpython/issues/117482
+# and https://github.com/python/cpython/pull/117660.
+script = textwrap.dedent('''
+text = repr(int.__str__)
+sch.send_nowait(text)
+''')
+
+exec(script)
+expected = rch.recv()
+
+interp = interpreters.create()
+interp.exec('from test.support import interpreters')
+interp.prepare_main(sch=sch)
+interp.exec(script)
+results = rch.recv()
+
+self.assertEqual(results, expected)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/Misc/NEWS.d/next/Core and
Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst b/Misc/NEWS.d/next/Core
and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst
new file mode 100644
index 00..ec1e7327b77f19
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and
Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst
@@ -0,0 +1,2 @@
+Unexpected slot wrappers are no longer created for builtin static types in
+subinterpreters.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 587632cecfba9d..7d01b680605a38 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -314,6 +314,16 @@ managed_static_type_state_clear(PyInterpreterState
*interp, PyTypeObject *self,
}
}
+static PyTypeObject *
+managed_static_type_get_def(PyTypeObject *self, int isbuiltin)
+{
+size_t index = managed_static_type_index_get(self);
+size_t full_index = isbuiltin
+? index
+: index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES;
+return &_PyRuntime.types.managed_static.types[full_index].def;
+}
+
// Also see _PyStaticType_InitBuiltin() and _PyStaticType_FiniBuiltin().
/* end static builtin helpers */
@@ -5840,7 +5850,6 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject
*type,
_PyStaticType_ClearWeakRefs(interp, type);
managed_static_type_state_clear(interp, type, isbuiltin, final);
-/* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
}
void
@@ -7850,7 +7859,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
return 0;
}
-static int add_operators(PyTypeObject *);
+static int add_operators(PyTypeObject *, PyTypeObject *);
static int add_tp_new_wrapper(PyTypeObject *type);
#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
@@ -8015,10 +8024,10 @@ type_dict_set_doc(PyTypeObject *type)
static int
-type_ready_fill_dict(PyTypeObject *type)
+type_ready_fill_dict(PyTypeObject *type, PyTypeObject *def)
{
/* Add type-specific descriptors to tp_dict */
-if (add_operators(type) < 0) {
+if (add_operators(type, def) < 0) {
return -1;
}
if (type_add_methods(type) < 0) {
@@ -8337,7 +8346,7 @@ type_ready_post_checks(PyTypeObject *type)
[Python-checkins] gh-121103: Put free-threaded libraries in `lib/python3.14t` (#121293)
https://github.com/python/cpython/commit/e8c91d90ba8fab410a27fad4f709cc73f6ffcbf4
commit: e8c91d90ba8fab410a27fad4f709cc73f6ffcbf4
branch: main
author: Sam Gross
committer: colesbury
date: 2024-07-11T16:21:37-04:00
summary:
gh-121103: Put free-threaded libraries in `lib/python3.14t` (#121293)
On POSIX systems, excluding macOS framework installs, the lib directory
for the free-threaded build now includes a "t" suffix to avoid conflicts
with a co-located default build installation.
files:
A Misc/NEWS.d/next/Build/2024-07-02-20-16-09.gh-issue-121103.TMef9j.rst
M Lib/site.py
M Lib/sysconfig/__init__.py
M Lib/test/test_embed.py
M Lib/test/test_getpath.py
M Lib/test/test_site.py
M Lib/test/test_sysconfig.py
M Lib/test/test_venv.py
M Makefile.pre.in
M Modules/getpath.c
M Modules/getpath.py
M configure
M configure.ac
diff --git a/Lib/site.py b/Lib/site.py
index daa56e158949db..460269433f021c 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -312,6 +312,10 @@ def joinuser(*args):
# Same to sysconfig.get_path('purelib', os.name+'_user')
def _get_path(userbase):
version = sys.version_info
+if hasattr(sys, 'abiflags') and 't' in sys.abiflags:
+abi_thread = 't'
+else:
+abi_thread = ''
implementation = _get_implementation()
implementation_lower = implementation.lower()
@@ -322,7 +326,7 @@ def _get_path(userbase):
if sys.platform == 'darwin' and sys._framework:
return f'{userbase}/lib/{implementation_lower}/site-packages'
-return f'{userbase}/lib/python{version[0]}.{version[1]}/site-packages'
+return
f'{userbase}/lib/python{version[0]}.{version[1]}{abi_thread}/site-packages'
def getuserbase():
@@ -390,6 +394,10 @@ def getsitepackages(prefixes=None):
implementation = _get_implementation().lower()
ver = sys.version_info
+if hasattr(sys, 'abiflags') and 't' in sys.abiflags:
+abi_thread = 't'
+else:
+abi_thread = ''
if os.sep == '/':
libdirs = [sys.platlibdir]
if sys.platlibdir != "lib":
@@ -397,7 +405,7 @@ def getsitepackages(prefixes=None):
for libdir in libdirs:
path = os.path.join(prefix, libdir,
-f"{implementation}{ver[0]}.{ver[1]}",
+
f"{implementation}{ver[0]}.{ver[1]}{abi_thread}",
"site-packages")
sitepackages.append(path)
else:
diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py
index 98a14e5d3a3187..83e057c177f8c0 100644
--- a/Lib/sysconfig/__init__.py
+++ b/Lib/sysconfig/__init__.py
@@ -27,10 +27,10 @@
_INSTALL_SCHEMES = {
'posix_prefix': {
-'stdlib':
'{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}',
-'platstdlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}',
-'purelib':
'{base}/lib/{implementation_lower}{py_version_short}/site-packages',
-'platlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}/site-packages',
+'stdlib':
'{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
+'platstdlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
+'purelib':
'{base}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
+'platlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
'include':
'{installed_base}/include/{implementation_lower}{py_version_short}{abiflags}',
'platinclude':
@@ -77,10 +77,10 @@
# Downstream distributors who patch posix_prefix/nt scheme are encouraged
to
# leave the following schemes unchanged
'posix_venv': {
-'stdlib':
'{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}',
-'platstdlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}',
-'purelib':
'{base}/lib/{implementation_lower}{py_version_short}/site-packages',
-'platlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}/site-packages',
+'stdlib':
'{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
+'platstdlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
+'purelib':
'{base}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
+'platlib':
'{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
'include':
'{installed_base}/include/{implementation_lower}{py_version_short}{abiflags}',
'platinclude':
@@ -148,11 +148,11 @@ def joinuser(*args):
'data': '{userbase}',
},
'posix_user': {
-'stdlib':
'{userbase}/{platlibdir}/{implementation_lower}{py_version_short}
[Python-checkins] [3.13] gh-117482: Fix Builtin Types Slot Wrappers (gh-121630)
https://github.com/python/cpython/commit/c6dbfbbe3c24cf2dd6a589904383f28cd1a1f4db commit: c6dbfbbe3c24cf2dd6a589904383f28cd1a1f4db branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: ericsnowcurrently date: 2024-07-11T20:47:38Z summary: [3.13] gh-117482: Fix Builtin Types Slot Wrappers (gh-121630) When builtin static types are initialized for a subinterpreter, various "tp" slots have already been inherited (for the main interpreter). This was interfering with the logic in add_operators() (in Objects/typeobject.c), causing a wrapper to get created when it shouldn't. This change fixes that by preserving the original data from the static type struct and checking that. (cherry picked from commit 5250a031332eb9499d5fc190d7287642e5a144b9, AKA gh-121602) Co-authored-by: Eric Snow files: A Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst M Include/internal/pycore_typeobject.h M Lib/test/test_types.py M Objects/typeobject.c diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 05f125f928ca68..124efccb48bebd 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -33,6 +33,7 @@ struct _types_runtime_state { struct { struct { PyTypeObject *type; +PyTypeObject def; int64_t interp_count; } types[_Py_MAX_MANAGED_STATIC_TYPES]; } managed_static; diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index fbca198aab5180..38a98828085e2f 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -10,6 +10,7 @@ import pickle import locale import sys +import textwrap import types import unittest.mock import weakref @@ -2345,5 +2346,40 @@ def ex(a, /, b, *, c): ) +class SubinterpreterTests(unittest.TestCase): + +@classmethod +def setUpClass(cls): +global interpreters +try: +from test.support import interpreters +except ModuleNotFoundError: +raise unittest.SkipTest('subinterpreters required') +import test.support.interpreters.channels + +@cpython_only +def test_slot_wrappers(self): +rch, sch = interpreters.channels.create() + +# For now it's sufficient to check int.__str__. +# See https://github.com/python/cpython/issues/117482 +# and https://github.com/python/cpython/pull/117660. +script = textwrap.dedent(''' +text = repr(int.__str__) +sch.send_nowait(text) +''') + +exec(script) +expected = rch.recv() + +interp = interpreters.create() +interp.exec('from test.support import interpreters') +interp.prepare_main(sch=sch) +interp.exec(script) +results = rch.recv() + +self.assertEqual(results, expected) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst new file mode 100644 index 00..ec1e7327b77f19 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst @@ -0,0 +1,2 @@ +Unexpected slot wrappers are no longer created for builtin static types in +subinterpreters. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4fc241e1190fc1..edcdc6e9c4f5c2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -314,6 +314,16 @@ managed_static_type_state_clear(PyInterpreterState *interp, PyTypeObject *self, } } +static PyTypeObject * +managed_static_type_get_def(PyTypeObject *self, int isbuiltin) +{ +size_t index = managed_static_type_index_get(self); +size_t full_index = isbuiltin +? index +: index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES; +return &_PyRuntime.types.managed_static.types[full_index].def; +} + // Also see _PyStaticType_InitBuiltin() and _PyStaticType_FiniBuiltin(). /* end static builtin helpers */ @@ -5668,7 +5678,6 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject *type, _PyStaticType_ClearWeakRefs(interp, type); managed_static_type_state_clear(interp, type, isbuiltin, final); -/* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */ } void @@ -7671,7 +7680,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) return 0; } -static int add_operators(PyTypeObject *); +static int add_operators(PyTypeObject *, PyTypeObject *); static int add_tp_new_wrapper(PyTypeObject *type); #define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING) @@ -7836,10 +7845,10 @@ type_dict_set_doc(PyTypeObject *type) static int -type_ready_fill_dict(PyTypeObject *type) +type_ready_fill_dict(PyTypeObject *type, PyTypeObject *def) { /* Add type-specific descriptors to tp_dict */ -if (add_operators(ty
[Python-checkins] [3.13] gh-121103: Put free-threaded libraries in `lib/python3.14t` (GH-121293) (#121631)
https://github.com/python/cpython/commit/35f7155bc39b8e5212b90a2ee96cb107b51e0e83 commit: 35f7155bc39b8e5212b90a2ee96cb107b51e0e83 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: colesbury date: 2024-07-11T21:00:28Z summary: [3.13] gh-121103: Put free-threaded libraries in `lib/python3.14t` (GH-121293) (#121631) On POSIX systems, excluding macOS framework installs, the lib directory for the free-threaded build now includes a "t" suffix to avoid conflicts with a co-located default build installation. (cherry picked from commit e8c91d90ba8fab410a27fad4f709cc73f6ffcbf4) Co-authored-by: Sam Gross files: A Misc/NEWS.d/next/Build/2024-07-02-20-16-09.gh-issue-121103.TMef9j.rst M Lib/site.py M Lib/sysconfig/__init__.py M Lib/test/test_embed.py M Lib/test/test_getpath.py M Lib/test/test_site.py M Lib/test/test_sysconfig.py M Lib/test/test_venv.py M Makefile.pre.in M Modules/getpath.c M Modules/getpath.py M configure M configure.ac diff --git a/Lib/site.py b/Lib/site.py index 95c7ebf2fdf146..650fa2b01835f9 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -312,6 +312,10 @@ def joinuser(*args): # Same to sysconfig.get_path('purelib', os.name+'_user') def _get_path(userbase): version = sys.version_info +if hasattr(sys, 'abiflags') and 't' in sys.abiflags: +abi_thread = 't' +else: +abi_thread = '' implementation = _get_implementation() implementation_lower = implementation.lower() @@ -322,7 +326,7 @@ def _get_path(userbase): if sys.platform == 'darwin' and sys._framework: return f'{userbase}/lib/{implementation_lower}/site-packages' -return f'{userbase}/lib/python{version[0]}.{version[1]}/site-packages' +return f'{userbase}/lib/python{version[0]}.{version[1]}{abi_thread}/site-packages' def getuserbase(): @@ -390,6 +394,10 @@ def getsitepackages(prefixes=None): implementation = _get_implementation().lower() ver = sys.version_info +if hasattr(sys, 'abiflags') and 't' in sys.abiflags: +abi_thread = 't' +else: +abi_thread = '' if os.sep == '/': libdirs = [sys.platlibdir] if sys.platlibdir != "lib": @@ -397,7 +405,7 @@ def getsitepackages(prefixes=None): for libdir in libdirs: path = os.path.join(prefix, libdir, -f"{implementation}{ver[0]}.{ver[1]}", + f"{implementation}{ver[0]}.{ver[1]}{abi_thread}", "site-packages") sitepackages.append(path) else: diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 98a14e5d3a3187..83e057c177f8c0 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -27,10 +27,10 @@ _INSTALL_SCHEMES = { 'posix_prefix': { -'stdlib': '{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}', -'platstdlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}', -'purelib': '{base}/lib/{implementation_lower}{py_version_short}/site-packages', -'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}/site-packages', +'stdlib': '{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}', +'platstdlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}', +'purelib': '{base}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages', +'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}/site-packages', 'include': '{installed_base}/include/{implementation_lower}{py_version_short}{abiflags}', 'platinclude': @@ -77,10 +77,10 @@ # Downstream distributors who patch posix_prefix/nt scheme are encouraged to # leave the following schemes unchanged 'posix_venv': { -'stdlib': '{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}', -'platstdlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}', -'purelib': '{base}/lib/{implementation_lower}{py_version_short}/site-packages', -'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}/site-packages', +'stdlib': '{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}', +'platstdlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}', +'purelib': '{base}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages', +'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}/site-packages', 'include': '{installed_base}/include/{implementation_lower}{py_version_short}{abiflags}', 'platinclude': @@ -148,11 +148,11 @@ def joinuser(
[Python-checkins] [3.12] gh-117482: Fix Builtin Types Slot Wrappers (gh-121632)
https://github.com/python/cpython/commit/0ec761a96a80f4b84b98aad5e784e4ac8f385c3f
commit: 0ec761a96a80f4b84b98aad5e784e4ac8f385c3f
branch: 3.12
author: Eric Snow
committer: ericsnowcurrently
date: 2024-07-11T21:20:08Z
summary:
[3.12] gh-117482: Fix Builtin Types Slot Wrappers (gh-121632)
When builtin static types are initialized for a subinterpreter, various "tp"
slots have already been inherited (for the main interpreter). This was
interfering with the logic in add_operators() (in Objects/typeobject.c),
causing a wrapper to get created when it shouldn't. This change fixes that by
preserving the original data from the static type struct and checking that.
(cherry picked from commit 5250a031332eb9499d5fc190d7287642e5a144b9, AKA
gh-121602)
Co-authored-by: Eric Snow
files:
A Misc/NEWS.d/next/Core and
Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst
M Lib/test/test_types.py
M Objects/typeobject.c
M Tools/c-analyzer/cpython/globals-to-fix.tsv
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index 5ffe4085f09548..ca41c76649ca99 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -9,6 +9,7 @@
import pickle
import locale
import sys
+import textwrap
import types
import unittest.mock
import weakref
@@ -2252,5 +2253,39 @@ def coro():
'close', 'throw'}))
+class SubinterpreterTests(unittest.TestCase):
+
+@classmethod
+def setUpClass(cls):
+global interpreters
+try:
+from test.support import interpreters
+except ModuleNotFoundError:
+raise unittest.SkipTest('subinterpreters required')
+
+@cpython_only
+def test_slot_wrappers(self):
+rch, sch = interpreters.create_channel()
+
+# For now it's sufficient to check int.__str__.
+# See https://github.com/python/cpython/issues/117482
+# and https://github.com/python/cpython/pull/117660.
+script = textwrap.dedent(f'''
+text = repr(int.__str__)
+sch = interpreters.SendChannel({sch.id})
+sch.send_nowait(text)
+''')
+
+exec(script)
+expected = rch.recv()
+
+interp = interpreters.create()
+interp.run('from test.support import interpreters')
+interp.run(script)
+results = rch.recv()
+
+self.assertEqual(results, expected)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/Misc/NEWS.d/next/Core and
Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst b/Misc/NEWS.d/next/Core
and Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst
new file mode 100644
index 00..ec1e7327b77f19
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and
Builtins/2024-07-10-15-43-54.gh-issue-117482.5WYaXR.rst
@@ -0,0 +1,2 @@
+Unexpected slot wrappers are no longer created for builtin static types in
+subinterpreters.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 9d05798e1715b4..1436b225f375a0 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -116,6 +116,18 @@ static_builtin_index_clear(PyTypeObject *self)
self->tp_subclasses = NULL;
}
+
+/* In 3.13+ this is stored in _PyRuntimeState. */
+static PyTypeObject static_type_defs[_Py_MAX_STATIC_BUILTIN_TYPES];
+
+static inline PyTypeObject *
+static_builtin_get_def(PyTypeObject *type)
+{
+size_t index = static_builtin_index_get(type);
+return &static_type_defs[index];
+}
+
+
static inline static_builtin_state *
static_builtin_state_get(PyInterpreterState *interp, PyTypeObject *self)
{
@@ -6982,7 +6994,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
return 0;
}
-static int add_operators(PyTypeObject *);
+static int add_operators(PyTypeObject *, PyTypeObject *);
static int add_tp_new_wrapper(PyTypeObject *type);
#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
@@ -7147,10 +7159,10 @@ type_dict_set_doc(PyTypeObject *type)
static int
-type_ready_fill_dict(PyTypeObject *type)
+type_ready_fill_dict(PyTypeObject *type, PyTypeObject *def)
{
/* Add type-specific descriptors to tp_dict */
-if (add_operators(type) < 0) {
+if (add_operators(type, def) < 0) {
return -1;
}
if (type_add_methods(type) < 0) {
@@ -7462,7 +7474,7 @@ type_ready_post_checks(PyTypeObject *type)
static int
-type_ready(PyTypeObject *type, int rerunbuiltin)
+type_ready(PyTypeObject *type, PyTypeObject *def, int rerunbuiltin)
{
_PyObject_ASSERT((PyObject *)type, !is_readying(type));
start_readying(type);
@@ -7499,7 +7511,7 @@ type_ready(PyTypeObject *type, int rerunbuiltin)
if (type_ready_set_new(type, rerunbuiltin) < 0) {
goto error;
}
-if (type_ready_fill_dict(type) < 0) {
+if (type_ready_fill_dict(type, def) < 0) {
goto error;
}
if (!rerunbuiltin) {
@@ -7551,7 +7563,7 @@ PyType_Ready(PyTypeObject *type)
type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
}
-return type_ready(type, 0);
+return typ
