[Python-checkins] [3.13] gh-132354: document return value for `asyncio.Task.cancel` (GH-132374) (#132465)

2025-04-13 Thread kumaraditya303
https://github.com/python/cpython/commit/ff66901d8a8753c11d4411e62376b26f17aa90cf
commit: ff66901d8a8753c11d4411e62376b26f17aa90cf
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: kumaraditya303 
date: 2025-04-13T07:41:26Z
summary:

[3.13] gh-132354: document return value for `asyncio.Task.cancel` (GH-132374) 
(#132465)

gh-132354: document return value for `asyncio.Task.cancel` (GH-132374)
(cherry picked from commit 64b066ad298506f715647c9a2524c9fbbc764cc2)

Co-authored-by: Felix Scherz 

files:
M Doc/library/asyncio-task.rst
M Misc/ACKS

diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index ddba9f20a3c03b..6c83ab94af3955 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -1336,7 +1336,10 @@ Task Object
 
   Request the Task to be cancelled.
 
-  This arranges for a :exc:`CancelledError` exception to be thrown
+  If the Task is already *done* or *cancelled*, return ``False``,
+  otherwise, return ``True``.
+
+  The method arranges for a :exc:`CancelledError` exception to be thrown
   into the wrapped coroutine on the next cycle of the event loop.
 
   The coroutine then has a chance to clean up or even deny the
diff --git a/Misc/ACKS b/Misc/ACKS
index f236c6400c2b30..3adb168f33c40a 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1644,6 +1644,7 @@ Andreas Schawo
 Neil Schemenauer
 David Scherer
 Wolfgang Scherer
+Felix Scherz
 Hynek Schlawack
 Bob Schmertz
 Gregor Schmid

___
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-123471: Make concurrent iteration over itertools.repeat safe under free-threading (#131247)

2025-04-13 Thread kumaraditya303
https://github.com/python/cpython/commit/9d127e83b9e6fbbb50ee047a0444c189a8770ada
commit: 9d127e83b9e6fbbb50ee047a0444c189a8770ada
branch: main
author: Pieter Eendebak 
committer: kumaraditya303 
date: 2025-04-13T13:26:58+05:30
summary:

gh-123471: Make concurrent iteration over itertools.repeat safe under 
free-threading (#131247)

files:
A Misc/NEWS.d/next/Library/2025-03-14-14-18-49.gh-issue-123471.sduBKk.rst
M Modules/itertoolsmodule.c

diff --git 
a/Misc/NEWS.d/next/Library/2025-03-14-14-18-49.gh-issue-123471.sduBKk.rst 
b/Misc/NEWS.d/next/Library/2025-03-14-14-18-49.gh-issue-123471.sduBKk.rst
new file mode 100644
index 00..b3829c72e5cad7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-03-14-14-18-49.gh-issue-123471.sduBKk.rst
@@ -0,0 +1 @@
+Make concurrent iterations over :class:`itertools.repeat` safe under 
free-threading.
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index c0448efed19a44..943c1e8607b38f 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -3628,10 +3628,14 @@ static PyObject *
 repeat_next(PyObject *op)
 {
 repeatobject *ro = repeatobject_CAST(op);
-if (ro->cnt == 0)
+Py_ssize_t cnt = FT_ATOMIC_LOAD_SSIZE_RELAXED(ro->cnt);
+if (cnt == 0) {
 return NULL;
-if (ro->cnt > 0)
-ro->cnt--;
+}
+if (cnt > 0) {
+cnt--;
+FT_ATOMIC_STORE_SSIZE_RELAXED(ro->cnt, cnt);
+}
 return Py_NewRef(ro->element);
 }
 

___
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-129169: update `asyncio.ensure_future` docs to suggest taskgroups

2025-04-13 Thread kumaraditya303
https://github.com/python/cpython/commit/00cf5eacc52d4790c23a24c835fb6b048cb27d8c
commit: 00cf5eacc52d4790c23a24c835fb6b048cb27d8c
branch: main
author: Case Zumbrum <[email protected]>
committer: kumaraditya303 
date: 2025-04-13T07:59:22Z
summary:

gh-129169: update `asyncio.ensure_future` docs to suggest taskgroups 


Co-authored-by: Kumar Aditya 

files:
M Doc/library/asyncio-future.rst

diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst
index 9dce0731411940..32771ba72e0002 100644
--- a/Doc/library/asyncio-future.rst
+++ b/Doc/library/asyncio-future.rst
@@ -51,12 +51,13 @@ Future Functions
 
.. important::
 
-  See also the :func:`create_task` function which is the
-  preferred way for creating new Tasks.
-
   Save a reference to the result of this function, to avoid
   a task disappearing mid-execution.
 
+  See also the :func:`create_task` function which is the
+  preferred way for creating new tasks or use :class:`asyncio.TaskGroup`
+  which keeps reference to the task internally.
+
.. versionchanged:: 3.5.1
   The function accepts any :term:`awaitable` object.
 

___
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-132099: Fix documentation for the BTPROTO_HCI protocol (GH-132118)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/1d97488c957f4595f8c3ea42e24c1995b23e39d4
commit: 1d97488c957f4595f8c3ea42e24c1995b23e39d4
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-04-13T18:39:22+03:00
summary:

gh-132099: Fix documentation for the BTPROTO_HCI protocol (GH-132118)

files:
M Doc/library/socket.rst

diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index 970698c5f644a2..2e38101c01d89d 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -149,19 +149,25 @@ created.  Socket addresses are represented as follows:
   :const:`BDADDR_LE_RANDOM`.
 
 .. versionchanged:: 3.14
-  Added ``cid`` and ``bdaddr_type`` fields.
+   Added ``cid`` and ``bdaddr_type`` fields.
 
   - :const:`BTPROTO_RFCOMM` accepts ``(bdaddr, channel)`` where ``bdaddr``
 is the Bluetooth address as a string and ``channel`` is an integer.
 
-  - :const:`BTPROTO_HCI` accepts ``(device_id,)`` where ``device_id`` is
-either an integer or a string with the Bluetooth address of the
-interface. (This depends on your OS; NetBSD and DragonFlyBSD expect
-a Bluetooth address while everything else expects an integer.)
+  - :const:`BTPROTO_HCI` accepts a format that depends on your OS.
+
+- On Linux it accepts a tuple ``(device_id,)`` where ``device_id``
+  is an integer specifying the number of the Bluetooth device.
+- On FreeBSD, NetBSD and DragonFly BSD it accepts ``bdaddr`` where 
``bdaddr``
+  is a :class:`bytes` object containing the Bluetooth address in a
+  string format. (ex. ``b'12:23:34:45:56:67'``)
 
 .. versionchanged:: 3.2
NetBSD and DragonFlyBSD support added.
 
+.. versionchanged:: 3.13.3
+   FreeBSD support added.
+
   - :const:`BTPROTO_SCO` accepts ``bdaddr`` where ``bdaddr`` is a
 :class:`bytes` object containing the Bluetooth address in a
 string format. (ex. ``b'12:23:34:45:56:67'``)
@@ -662,16 +668,15 @@ Constants
These constants describe the Bluetooth address type when binding or
connecting a :const:`BTPROTO_L2CAP` socket.
 
-.. versionadded:: 3.14
+   .. versionadded:: 3.14
 
 .. data:: HCI_FILTER
   HCI_TIME_STAMP
   HCI_DATA_DIR
 
-   For use with :const:`BTPROTO_HCI`. :const:`HCI_FILTER` is not
-   available for NetBSD or DragonFlyBSD. :const:`HCI_TIME_STAMP` and
-   :const:`HCI_DATA_DIR` are not available for FreeBSD, NetBSD, or
-   DragonFlyBSD.
+   For use with :const:`BTPROTO_HCI`. :const:`!HCI_FILTER` is only
+   available on Linux and FreeBSD. :const:`!HCI_TIME_STAMP` and
+   :const:`!HCI_DATA_DIR` are only available on Linux.
 
 .. data:: AF_QIPCRTR
 

___
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-132106: Ensure that running `logging.handlers.QueueListener… (GH-132471)

2025-04-13 Thread vsajip
https://github.com/python/cpython/commit/1dcdac6e084471c14b4690ae9154b928e93a7222
commit: 1dcdac6e084471c14b4690ae9154b928e93a7222
branch: 3.13
author: Vinay Sajip 
committer: vsajip 
date: 2025-04-13T13:00:50+01:00
summary:

[3.13] gh-132106: Ensure that running `logging.handlers.QueueListener… 
(GH-132471)

Cherry-picked using 5863cd70b8782313b52bb8c71a4127d7ea4c50e9

files:
A Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst
M Doc/library/logging.handlers.rst
M Lib/logging/handlers.py
M Lib/test/test_logging.py

diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index 5a081f9e7add99..e63c253e123552 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -1172,6 +1172,10 @@ possible, while any potentially slow operations (such as 
sending an email via
   This starts up a background thread to monitor the queue for
   LogRecords to process.
 
+  .. versionchanged:: next
+ Raises :exc:`RuntimeError` if called and the listener is already
+ running.
+
.. method:: stop()
 
   Stops the listener.
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index da9c59c119f3db..d3ea06c731ef89 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -1545,6 +1545,9 @@ def start(self):
 This starts up a background thread to monitor the queue for
 LogRecords to process.
 """
+if self._thread is not None:
+raise RuntimeError("Listener already started")
+
 self._thread = t = threading.Thread(target=self._monitor)
 t.daemon = True
 t.start()
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 678c23dad67faa..58e0381c4aa934 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -4300,8 +4300,6 @@ def test_formatting(self):
 self.assertEqual(formatted_msg, log_record.msg)
 self.assertEqual(formatted_msg, log_record.message)
 
[email protected](hasattr(logging.handlers, 'QueueListener'),
- 'logging.handlers.QueueListener required for this 
test')
 def test_queue_listener(self):
 handler = TestHandler(support.Matcher())
 listener = logging.handlers.QueueListener(self.queue, handler)
@@ -4336,8 +4334,18 @@ def test_queue_listener(self):
 self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='6'))
 handler.close()
 
[email protected](hasattr(logging.handlers, 'QueueListener'),
- 'logging.handlers.QueueListener required for this 
test')
+# doesn't hurt to call stop() more than once.
+listener.stop()
+self.assertIsNone(listener._thread)
+
+def test_queue_listener_multi_start(self):
+handler = TestHandler(support.Matcher())
+listener = logging.handlers.QueueListener(self.queue, handler)
+listener.start()
+self.assertRaises(RuntimeError, listener.start)
+listener.stop()
+self.assertIsNone(listener._thread)
+
 def test_queue_listener_with_StreamHandler(self):
 # Test that traceback and stack-info only appends once (bpo-34334, 
bpo-46755).
 listener = logging.handlers.QueueListener(self.queue, self.root_hdlr)
@@ -4352,8 +4360,6 @@ def test_queue_listener_with_StreamHandler(self):
 self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1)
 self.assertEqual(self.stream.getvalue().strip().count('Stack'), 1)
 
[email protected](hasattr(logging.handlers, 'QueueListener'),
- 'logging.handlers.QueueListener required for this 
test')
 def test_queue_listener_with_multiple_handlers(self):
 # Test that queue handler format doesn't affect other handler formats 
(bpo-35726).
 self.que_hdlr.setFormatter(self.root_formatter)
diff --git 
a/Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst 
b/Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst
new file mode 100644
index 00..b6d58a29f9b42f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst
@@ -0,0 +1,2 @@
+:meth:`QueueListener.start ` now
+raises a :exc:`RuntimeError` if the listener is already started.

___
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-125866: Support complete "file:" URLs in urllib (#132378)

2025-04-13 Thread barneygale
https://github.com/python/cpython/commit/ccad61e35d240972d14f993507566706fbf419f1
commit: ccad61e35d240972d14f993507566706fbf419f1
branch: main
author: Barney Gale 
committer: barneygale 
date: 2025-04-14T01:49:02+01:00
summary:

GH-125866: Support complete "file:" URLs in urllib (#132378)

Add optional *add_scheme* argument to `urllib.request.pathname2url()`; when
set to true, a complete URL is returned. Likewise add optional
*require_scheme* argument to `url2pathname()`; when set to true, a complete
URL is accepted.

Co-authored-by: Bénédikt Tran <[email protected]>

files:
A Misc/NEWS.d/next/Library/2025-04-10-21-43-04.gh-issue-125866.EZ9X8D.rst
M Doc/library/urllib.request.rst
M Doc/whatsnew/3.14.rst
M Lib/pathlib/__init__.py
M Lib/test/test_pathlib/test_pathlib.py
M Lib/test/test_urllib.py
M Lib/test/test_urllib2.py
M Lib/test/test_urllib2net.py
M Lib/urllib/request.py

diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index edfc249eb43c78..a5f1b9b292a85a 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -146,16 +146,19 @@ The :mod:`urllib.request` module defines the following 
functions:
attribute to modify its position in the handlers list.
 
 
-.. function:: pathname2url(path)
+.. function:: pathname2url(path, *, add_scheme=False)
 
Convert the given local path to a ``file:`` URL. This function uses
-   :func:`~urllib.parse.quote` function to encode the path. For historical
-   reasons, the return value omits the ``file:`` scheme prefix. This example
-   shows the function being used on Windows::
+   :func:`~urllib.parse.quote` function to encode the path.
+
+   If *add_scheme* is false (the default), the return value omits the
+   ``file:`` scheme prefix. Set *add_scheme* to true to return a complete URL.
+
+   This example shows the function being used on Windows::
 
   >>> from urllib.request import pathname2url
   >>> path = 'C:\\Program Files'
-  >>> 'file:' + pathname2url(path)
+  >>> pathname2url(path, add_scheme=True)
   'file:///C:/Program%20Files'
 
.. versionchanged:: 3.14
@@ -168,17 +171,25 @@ The :mod:`urllib.request` module defines the following 
functions:
   sections. For example, the path ``/etc/hosts`` is converted to
   the URL ``///etc/hosts``.
 
+   .. versionchanged:: next
+  The *add_scheme* argument was added.
+
 
-.. function:: url2pathname(url)
+.. function:: url2pathname(url, *, require_scheme=False)
 
Convert the given ``file:`` URL to a local path. This function uses
-   :func:`~urllib.parse.unquote` to decode the URL. For historical reasons,
-   the given value *must* omit the ``file:`` scheme prefix. This example shows
-   the function being used on Windows::
+   :func:`~urllib.parse.unquote` to decode the URL.
+
+   If *require_scheme* is false (the default), the given value should omit a
+   ``file:`` scheme prefix. If *require_scheme* is set to true, the given
+   value should include the prefix; a :exc:`~urllib.error.URLError` is raised
+   if it doesn't.
+
+   This example shows the function being used on Windows::
 
   >>> from urllib.request import url2pathname
   >>> url = 'file:///C:/Program%20Files'
-  >>> url2pathname(url.removeprefix('file:'))
+  >>> url2pathname(url, require_scheme=True)
   'C:\\Program Files'
 
.. versionchanged:: 3.14
@@ -193,6 +204,9 @@ The :mod:`urllib.request` module defines the following 
functions:
   returned (as before), and on other platforms a
   :exc:`~urllib.error.URLError` is raised.
 
+   .. versionchanged:: next
+  The *require_scheme* argument was added.
+
 
 .. function:: getproxies()
 
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 421d12660b7956..0e30500fc9b997 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -1218,16 +1218,20 @@ urllib
   supporting SHA-256 digest authentication as specified in :rfc:`7616`.
   (Contributed by Calvin Bui in :gh:`128193`.)
 
-* Improve standards compliance when parsing and emitting ``file:`` URLs.
+* Improve ergonomics and standards compliance when parsing and emitting
+  ``file:`` URLs.
 
   In :func:`urllib.request.url2pathname`:
 
+  - Accept a complete URL when the new *require_scheme* argument is set to
+true.
   - Discard URL authorities that resolve to a local IP address.
   - Raise :exc:`~urllib.error.URLError` if a URL authority doesn't resolve
-to ``localhost``, except on Windows where we return a UNC path.
+to a local IP address, except on Windows where we return a UNC path.
 
   In :func:`urllib.request.pathname2url`:
 
+  - Return a complete URL when the new *add_scheme* argument is set to true.
   - Include an empty URL authority when a path begins with a slash. For
 example, the path ``/etc/hosts`` is converted to the URL ``///etc/hosts``.
 
diff --git a/Lib/pathlib/__init__.py b/Lib/pathlib/__init__.py
index 43a5440e0132ff..12cf9f579cb32d 100644
--- a/Lib

[Python-checkins] [3.13] gh-124986: Fix test_no_leaking in test_subprocess on NetBSD and FreeBSD (GH-132476) (GH-132498)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/ff9198dab3b66bd31d33bae674181f2d24124ea2
commit: ff9198dab3b66bd31d33bae674181f2d24124ea2
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka 
date: 2025-04-14T06:38:13Z
summary:

[3.13] gh-124986: Fix test_no_leaking in test_subprocess on NetBSD and FreeBSD 
(GH-132476) (GH-132498)

On platforms where the file descriptor limit is larger than FD_SETSIZE
that test was always skipped (FreeBSD) or always failing (NetBSD).
(cherry picked from commit f7b24ffefda839f367b048c06879df6bded128a1)

Co-authored-by: Serhiy Storchaka 

files:
M Lib/test/test_subprocess.py

diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index bf9b32c8ef..7d72737e9cb066 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -40,6 +40,10 @@
 import grp
 except ImportError:
 grp = None
+try:
+import resource
+except ImportError:
+resource = None
 
 try:
 import fcntl
@@ -1210,6 +1214,16 @@ def test_no_leaking(self):
 max_handles = 1026 # too much for most UNIX systems
 else:
 max_handles = 2050 # too much for (at least some) Windows setups
+if resource:
+# And if it is not too much, try to make it too much.
+try:
+soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
+if soft > 1024:
+resource.setrlimit(resource.RLIMIT_NOFILE, (1024, hard))
+self.addCleanup(resource.setrlimit, resource.RLIMIT_NOFILE,
+(soft, hard))
+except (OSError, ValueError):
+pass
 handles = []
 tmpdir = tempfile.mkdtemp()
 try:
@@ -1224,7 +1238,9 @@ def test_no_leaking(self):
 else:
 self.skipTest("failed to reach the file descriptor limit "
 "(tried %d)" % max_handles)
-# Close a couple of them (should be enough for a subprocess)
+# Close a couple of them (should be enough for a subprocess).
+# Close lower file descriptors, so select() will work.
+handles.reverse()
 for i in range(10):
 os.close(handles.pop())
 # Loop creating some subprocesses. If one of them leaks some fds,

___
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-132099: Fix documentation for the BTPROTO_HCI protocol (GH-132118) (GH-132482)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/54e1b6eef7898b79bafa912623523a5fa0b1
commit: 54e1b6eef7898b79bafa912623523a5fa0b1
branch: 3.13
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-04-13T16:27:41Z
summary:

[3.13] gh-132099: Fix documentation for the BTPROTO_HCI protocol (GH-132118) 
(GH-132482)

(cherry picked from commit 1d97488c957f4595f8c3ea42e24c1995b23e39d4)

files:
M Doc/library/socket.rst

diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index e5baa3a002a01e..52b993bd81e96b 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -143,14 +143,20 @@ created.  Socket addresses are represented as follows:
   - :const:`BTPROTO_RFCOMM` accepts ``(bdaddr, channel)`` where ``bdaddr``
 is the Bluetooth address as a string and ``channel`` is an integer.
 
-  - :const:`BTPROTO_HCI` accepts ``(device_id,)`` where ``device_id`` is
-either an integer or a string with the Bluetooth address of the
-interface. (This depends on your OS; NetBSD and DragonFlyBSD expect
-a Bluetooth address while everything else expects an integer.)
+  - :const:`BTPROTO_HCI` accepts a format that depends on your OS.
+
+- On Linux it accepts a tuple ``(device_id,)`` where ``device_id``
+  is an integer specifying the number of the Bluetooth device.
+- On FreeBSD, NetBSD and DragonFly BSD it accepts ``bdaddr`` where 
``bdaddr``
+  is a :class:`bytes` object containing the Bluetooth address in a
+  string format. (ex. ``b'12:23:34:45:56:67'``)
 
 .. versionchanged:: 3.2
NetBSD and DragonFlyBSD support added.
 
+.. versionchanged:: 3.13.3
+   FreeBSD support added.
+
   - :const:`BTPROTO_SCO` accepts ``bdaddr`` where ``bdaddr`` is a
 :class:`bytes` object containing the Bluetooth address in a
 string format. (ex. ``b'12:23:34:45:56:67'``) This protocol is not
@@ -630,10 +636,9 @@ Constants
   HCI_TIME_STAMP
   HCI_DATA_DIR
 
-   For use with :const:`BTPROTO_HCI`. :const:`HCI_FILTER` is not
-   available for NetBSD or DragonFlyBSD. :const:`HCI_TIME_STAMP` and
-   :const:`HCI_DATA_DIR` are not available for FreeBSD, NetBSD, or
-   DragonFlyBSD.
+   For use with :const:`BTPROTO_HCI`. :const:`!HCI_FILTER` is only
+   available on Linux and FreeBSD. :const:`!HCI_TIME_STAMP` and
+   :const:`!HCI_DATA_DIR` are only available on Linux.
 
 .. data:: AF_QIPCRTR
 

___
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-132111: Document dataclasses.InitVar (#132446)

2025-04-13 Thread ericvsmith
https://github.com/python/cpython/commit/281fc338fdf57ef119e213bf1b2c772261c359c1
commit: 281fc338fdf57ef119e213bf1b2c772261c359c1
branch: main
author: Tapeline 
committer: ericvsmith 
date: 2025-04-13T12:47:44-04:00
summary:

gh-132111: Document dataclasses.InitVar (#132446)

files:
M Doc/library/dataclasses.rst

diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst
index 0bc171da4eefc7..72612211b43d5e 100644
--- a/Doc/library/dataclasses.rst
+++ b/Doc/library/dataclasses.rst
@@ -344,6 +344,15 @@ Module contents
Other attributes may exist, but they are private and must not be
inspected or relied on.
 
+.. class:: InitVar
+
+   ``InitVar[T]`` type annotations describe variables that are :ref:`init-only
+   `. Fields annotated with :class:`!InitVar`
+   are considered pseudo-fields, and thus are neither returned by the
+   :func:`fields` function nor used in any way except adding them as
+   parameters to :meth:`~object.__init__` and an optional
+   :meth:`__post_init__`.
+
 .. function:: fields(class_or_instance)
 
Returns a tuple of :class:`Field` objects that define the fields for this
@@ -600,8 +609,8 @@ Init-only variables
 
 Another place where :func:`@dataclass ` inspects a type annotation 
is to
 determine if a field is an init-only variable.  It does this by seeing
-if the type of a field is of type ``dataclasses.InitVar``.  If a field
-is an ``InitVar``, it is considered a pseudo-field called an init-only
+if the type of a field is of type :class:`InitVar`.  If a field
+is an :class:`InitVar`, it is considered a pseudo-field called an init-only
 field.  As it is not a true field, it is not returned by the
 module-level :func:`fields` function.  Init-only fields are added as
 parameters to the generated :meth:`~object.__init__` method, and are passed to

___
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-132111: Document dataclasses.InitVar (GH-132446) (#132483)

2025-04-13 Thread ericvsmith
https://github.com/python/cpython/commit/d021b719ed87d4ce6e03913361564c1c79215123
commit: d021b719ed87d4ce6e03913361564c1c79215123
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: ericvsmith 
date: 2025-04-13T16:53:40Z
summary:

[3.13] gh-132111: Document dataclasses.InitVar (GH-132446) (#132483)

gh-132111: Document dataclasses.InitVar (GH-132446)
(cherry picked from commit 281fc338fdf57ef119e213bf1b2c772261c359c1)

Co-authored-by: Tapeline 

files:
M Doc/library/dataclasses.rst

diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst
index 134ba0fa9b4b9f..47b2d559989696 100644
--- a/Doc/library/dataclasses.rst
+++ b/Doc/library/dataclasses.rst
@@ -347,6 +347,15 @@ Module contents
Other attributes may exist, but they are private and must not be
inspected or relied on.
 
+.. class:: InitVar
+
+   ``InitVar[T]`` type annotations describe variables that are :ref:`init-only
+   `. Fields annotated with :class:`!InitVar`
+   are considered pseudo-fields, and thus are neither returned by the
+   :func:`fields` function nor used in any way except adding them as
+   parameters to :meth:`~object.__init__` and an optional
+   :meth:`__post_init__`.
+
 .. function:: fields(class_or_instance)
 
Returns a tuple of :class:`Field` objects that define the fields for this
@@ -595,8 +604,8 @@ Init-only variables
 
 Another place where :func:`@dataclass ` inspects a type annotation 
is to
 determine if a field is an init-only variable.  It does this by seeing
-if the type of a field is of type ``dataclasses.InitVar``.  If a field
-is an ``InitVar``, it is considered a pseudo-field called an init-only
+if the type of a field is of type :class:`InitVar`.  If a field
+is an :class:`InitVar`, it is considered a pseudo-field called an init-only
 field.  As it is not a true field, it is not returned by the
 module-level :func:`fields` function.  Init-only fields are added as
 parameters to the generated :meth:`~object.__init__` method, and are passed to

___
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-124986: Fix test_no_leaking in test_subprocess on NetBSD and FreeBSD (GH-132476)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/f7b24ffefda839f367b048c06879df6bded128a1
commit: f7b24ffefda839f367b048c06879df6bded128a1
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-04-14T09:15:12+03:00
summary:

gh-124986: Fix test_no_leaking in test_subprocess on NetBSD and FreeBSD 
(GH-132476)

On platforms where the file descriptor limit is larger than FD_SETSIZE
that test was always skipped (FreeBSD) or always failing (NetBSD).

files:
M Lib/test/test_subprocess.py

diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 81d97a88f07bdd..3cb755cd56cac8 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -41,6 +41,10 @@
 import grp
 except ImportError:
 grp = None
+try:
+import resource
+except ImportError:
+resource = None
 
 try:
 import fcntl
@@ -1211,6 +1215,16 @@ def test_no_leaking(self):
 max_handles = 1026 # too much for most UNIX systems
 else:
 max_handles = 2050 # too much for (at least some) Windows setups
+if resource:
+# And if it is not too much, try to make it too much.
+try:
+soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
+if soft > 1024:
+resource.setrlimit(resource.RLIMIT_NOFILE, (1024, hard))
+self.addCleanup(resource.setrlimit, resource.RLIMIT_NOFILE,
+(soft, hard))
+except (OSError, ValueError):
+pass
 handles = []
 tmpdir = tempfile.mkdtemp()
 try:
@@ -1225,7 +1239,9 @@ def test_no_leaking(self):
 else:
 self.skipTest("failed to reach the file descriptor limit "
 "(tried %d)" % max_handles)
-# Close a couple of them (should be enough for a subprocess)
+# Close a couple of them (should be enough for a subprocess).
+# Close lower file descriptors, so select() will work.
+handles.reverse()
 for i in range(10):
 os.close(handles.pop())
 # Loop creating some subprocesses. If one of them leaks some fds,

___
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-115322: fix ctypes call_function audit hook on 32-bit platforms (GH-132496)

2025-04-13 Thread gpshead
https://github.com/python/cpython/commit/7a29c9883f4cf61372895362e865f7d2f99bd4ca
commit: 7a29c9883f4cf61372895362e865f7d2f99bd4ca
branch: main
author: Gregory P. Smith 
committer: gpshead 
date: 2025-04-14T06:22:29Z
summary:

GH-115322: fix ctypes call_function audit hook on 32-bit platforms (GH-132496)

* GH-115322: fix ctypes call_function audit hook on 32-bit platforms.

It was using a signed conversion to communicate the function id (pointer) value.

files:
M Lib/test/audit-tests.py
M Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst
M Modules/_ctypes/callproc.c

diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py
index 3d81f27e5cb46d..08b638e4b8d524 100644
--- a/Lib/test/audit-tests.py
+++ b/Lib/test/audit-tests.py
@@ -311,10 +311,10 @@ def test_ctypes_call_function():
 
 with TestHook() as hook:
 _ctypes.call_function(ctypes._memmove_addr, (0, 0, 0))
-assert ("ctypes.call_function", (ctypes._memmove_addr, (0, 0, 0))) in 
hook.seen
+assert ("ctypes.call_function", (ctypes._memmove_addr, (0, 0, 0))) in 
hook.seen, f"{ctypes._memmove_addr=} {hook.seen=}"
 
 ctypes.CFUNCTYPE(ctypes.c_voidp)(ctypes._memset_addr)(1, 0, 0)
-assert ("ctypes.call_function", (ctypes._memset_addr, (1, 0, 0))) in 
hook.seen
+assert ("ctypes.call_function", (ctypes._memset_addr, (1, 0, 0))) in 
hook.seen, f"{ctypes._memset_addr=} {hook.seen=}"
 
 with TestHook() as hook:
 ctypes.cast(ctypes.c_voidp(0), ctypes.POINTER(ctypes.c_char))
diff --git 
a/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst 
b/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst
index a09e1f1fcdcab7..8eb5c3ed04ee2c 100644
--- a/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst
+++ b/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst
@@ -1,4 +1,5 @@
 The underlying extension modules behind :mod:`readline`:, :mod:`subprocess`,
 and :mod:`ctypes` now raise audit events on previously uncovered code paths
 that could lead to file system access related to C function calling and
-external binary execution.
+external binary execution.  The ``ctypes.call_function`` audit hook has also
+been fixed to use an unsigned value for its ``function pointer``.
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index f5db49ff4bc61c..cb8ab7b33a2953 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -1199,8 +1199,17 @@ PyObject *_ctypes_callproc(ctypes_state *st,
 PyObject *retval = NULL;
 
 // Both call_function and call_cdeclfunction call us:
+#if SIZEOF_VOID_P == SIZEOF_LONG
+if (PySys_Audit("ctypes.call_function", "kO",
+(unsigned long)pProc, argtuple) < 0) {
+#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
+if (PySys_Audit("ctypes.call_function", "KO",
+(unsigned long long)pProc, argtuple) < 0) {
+#else
+# warning "unexpected pointer size, you may see odd values in audit hooks"
 if (PySys_Audit("ctypes.call_function", "nO",
 (Py_ssize_t)pProc, argtuple) < 0) {
+#endif
 return NULL;
 }
 

___
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-71339: Use new assertion methods in the urllib tests (GH-129056)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/f98b9b4cbb7905c9af45718505389d171ca3c590
commit: f98b9b4cbb7905c9af45718505389d171ca3c590
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-04-14T09:24:41+03:00
summary:

gh-71339: Use new assertion methods in the urllib tests (GH-129056)

files:
M Lib/test/test_urllib.py
M Lib/test/test_urllib2.py
M Lib/test/test_urllib2_localnet.py
M Lib/test/test_urllibnet.py
M Lib/test/test_urlparse.py

diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index abfbed8840ca03..da3db2f4e550fb 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -121,9 +121,7 @@ def test_interface(self):
 # Make sure object returned by urlopen() has the specified methods
 for attr in ("read", "readline", "readlines", "fileno",
  "close", "info", "geturl", "getcode", "__iter__"):
-self.assertTrue(hasattr(self.returned_obj, attr),
- "object returned by urlopen() lacks %s attribute" %
- attr)
+self.assertHasAttr(self.returned_obj, attr)
 
 def test_read(self):
 self.assertEqual(self.text, self.returned_obj.read())
@@ -544,9 +542,7 @@ def test_interface(self):
 # Make sure object returned by urlopen() has the specified methods
 for attr in ("read", "readline", "readlines",
  "close", "info", "geturl", "getcode", "__iter__"):
-self.assertTrue(hasattr(self.text_url_resp, attr),
- "object returned by urlopen() lacks %s attribute" %
- attr)
+self.assertHasAttr(self.text_url_resp, attr)
 
 def test_info(self):
 self.assertIsInstance(self.text_url_resp.info(), email.message.Message)
diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py
index f44d324b3ab763..b1229607c516c7 100644
--- a/Lib/test/test_urllib2.py
+++ b/Lib/test/test_urllib2.py
@@ -1193,15 +1193,15 @@ def test_errors(self):
 r = MockResponse(200, "OK", {}, "", url)
 newr = h.http_response(req, r)
 self.assertIs(r, newr)
-self.assertFalse(hasattr(o, "proto"))  # o.error not called
+self.assertNotHasAttr(o, "proto")  # o.error not called
 r = MockResponse(202, "Accepted", {}, "", url)
 newr = h.http_response(req, r)
 self.assertIs(r, newr)
-self.assertFalse(hasattr(o, "proto"))  # o.error not called
+self.assertNotHasAttr(o, "proto")  # o.error not called
 r = MockResponse(206, "Partial content", {}, "", url)
 newr = h.http_response(req, r)
 self.assertIs(r, newr)
-self.assertFalse(hasattr(o, "proto"))  # o.error not called
+self.assertNotHasAttr(o, "proto")  # o.error not called
 # anything else calls o.error (and MockOpener returns None, here)
 r = MockResponse(502, "Bad gateway", {}, "", url)
 self.assertIsNone(h.http_response(req, r))
@@ -1416,7 +1416,7 @@ def http_open(self, req):
 response = opener.open('http://example.com/')
 expected = b'GET ' + result + b' '
 request = handler.last_buf
-self.assertTrue(request.startswith(expected), repr(request))
+self.assertStartsWith(request, expected)
 
 def test_redirect_head_request(self):
 from_url = "http://example.com/a.html";
@@ -1906,9 +1906,9 @@ def test_HTTPError_interface(self):
 url = code = fp = None
 hdrs = 'Content-Length: 42'
 err = urllib.error.HTTPError(url, code, msg, hdrs, fp)
-self.assertTrue(hasattr(err, 'reason'))
+self.assertHasAttr(err, 'reason')
 self.assertEqual(err.reason, 'something bad happened')
-self.assertTrue(hasattr(err, 'headers'))
+self.assertHasAttr(err, 'headers')
 self.assertEqual(err.headers, 'Content-Length: 42')
 expected_errmsg = 'HTTP Error %s: %s' % (err.code, err.msg)
 self.assertEqual(str(err), expected_errmsg)
diff --git a/Lib/test/test_urllib2_localnet.py 
b/Lib/test/test_urllib2_localnet.py
index 9cb15d61c2ad4d..9186436183aae1 100644
--- a/Lib/test/test_urllib2_localnet.py
+++ b/Lib/test/test_urllib2_localnet.py
@@ -606,8 +606,7 @@ def test_basic(self):
 handler = self.start_server()
 with urllib.request.urlopen("http://localhost:%s"; % handler.port) as 
open_url:
 for attr in ("read", "close", "info", "geturl"):
-self.assertTrue(hasattr(open_url, attr), "object returned from 
"
- "urlopen lacks the %s attribute" % attr)
+self.assertHasAttr(open_url, attr)
 self.assertTrue(open_url.read(), "calling 'read' failed")
 
 def test_info(self):
diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py
index ce4e60e3a8011d..1a42c35dc49b9e 100644
--- a/Lib/test/test_urllibnet.py
+++ b/Lib/test/test_urllibnet.py
@@ -71,8 +71,7 @@ d

[Python-checkins] gh-71339: Use new assertion methods in the http tests (GH-129058)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/7076d076c27687140adc64ad495ea82f6eb5b3ce
commit: 7076d076c27687140adc64ad495ea82f6eb5b3ce
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-04-14T09:24:54+03:00
summary:

gh-71339: Use new assertion methods in the http tests (GH-129058)

files:
M Lib/test/test_http_cookiejar.py
M Lib/test/test_http_cookies.py
M Lib/test/test_httplib.py
M Lib/test/test_httpservers.py

diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py
index cf02c5b43a2e43..6bc33b15ec32e9 100644
--- a/Lib/test/test_http_cookiejar.py
+++ b/Lib/test/test_http_cookiejar.py
@@ -1537,7 +1537,7 @@ def test_netscape_example_1(self):
 h = req.get_header("Cookie")
 self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h)
 self.assertIn("CUSTOMER=WILE_E_COYOTE", h)
-self.assertTrue(h.startswith("SHIPPING=FEDEX;"))
+self.assertStartsWith(h, "SHIPPING=FEDEX;")
 
 def test_netscape_example_2(self):
 # Second Example transaction sequence:
diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py
index d945de23493f20..2fbc142de2fd34 100644
--- a/Lib/test/test_http_cookies.py
+++ b/Lib/test/test_http_cookies.py
@@ -180,7 +180,7 @@ def test_special_attrs(self):
 C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"')
 C['Customer']['expires'] = 0
 # can't test exact output, it always depends on current date/time
-self.assertTrue(C.output().endswith('GMT'))
+self.assertEndsWith(C.output(), 'GMT')
 
 # loading 'expires'
 C = cookies.SimpleCookie()
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 75b748aee05940..38429ad480ff1c 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -273,7 +273,7 @@ def test_ipv6host_header(self):
 sock = FakeSocket('')
 conn.sock = sock
 conn.request('GET', '/foo')
-self.assertTrue(sock.data.startswith(expected))
+self.assertStartsWith(sock.data, expected)
 
 expected = b'GET /foo HTTP/1.1\r\nHost: [2001:102A::]\r\n' \
b'Accept-Encoding: identity\r\n\r\n'
@@ -281,7 +281,7 @@ def test_ipv6host_header(self):
 sock = FakeSocket('')
 conn.sock = sock
 conn.request('GET', '/foo')
-self.assertTrue(sock.data.startswith(expected))
+self.assertStartsWith(sock.data, expected)
 
 expected = b'GET /foo HTTP/1.1\r\nHost: [fe80::]\r\n' \
b'Accept-Encoding: identity\r\n\r\n'
@@ -289,7 +289,7 @@ def test_ipv6host_header(self):
 sock = FakeSocket('')
 conn.sock = sock
 conn.request('GET', '/foo')
-self.assertTrue(sock.data.startswith(expected))
+self.assertStartsWith(sock.data, expected)
 
 expected = b'GET /foo HTTP/1.1\r\nHost: [fe80::]:81\r\n' \
b'Accept-Encoding: identity\r\n\r\n'
@@ -297,7 +297,7 @@ def test_ipv6host_header(self):
 sock = FakeSocket('')
 conn.sock = sock
 conn.request('GET', '/foo')
-self.assertTrue(sock.data.startswith(expected))
+self.assertStartsWith(sock.data, expected)
 
 def test_malformed_headers_coped_with(self):
 # Issue 19996
@@ -335,9 +335,9 @@ def test_parse_all_octets(self):
 self.assertIsNotNone(resp.getheader('obs-text'))
 self.assertIn('obs-text', resp.msg)
 for folded in (resp.getheader('obs-fold'), resp.msg['obs-fold']):
-self.assertTrue(folded.startswith('text'))
+self.assertStartsWith(folded, 'text')
 self.assertIn(' folded with space', folded)
-self.assertTrue(folded.endswith('folded with tab'))
+self.assertEndsWith(folded, 'folded with tab')
 
 def test_invalid_headers(self):
 conn = client.HTTPConnection('example.com')
@@ -1000,8 +1000,7 @@ def test_send_file(self):
 sock = FakeSocket(body)
 conn.sock = sock
 conn.request('GET', '/foo', body)
-self.assertTrue(sock.data.startswith(expected), '%r != %r' %
-(sock.data[:len(expected)], expected))
+self.assertStartsWith(sock.data, expected)
 
 def test_send(self):
 expected = b'this is a test this is only a test'
@@ -1564,7 +1563,7 @@ def mypeek(n=-1):
 # then unbounded peek
 p2 = resp.peek()
 self.assertGreaterEqual(len(p2), len(p))
-self.assertTrue(p2.startswith(p))
+self.assertStartsWith(p2, p)
 next = resp.read(len(p2))
 self.assertEqual(next, p2)
 else:
@@ -1589,7 +1588,7 @@ def _verify_readline(self, readline, expected, limit=5):
 line = readline(limit)
 if line and line != b"foo":
 if len(line) < 5:
-self.assertTrue(line.endswith(b"\n"))
+self.assertEndsWith(line,

[Python-checkins] gh-71339: Use new assertion methods in the email tests (GH-129055)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/522766aa23b110257d5e31128ff5a5575715e880
commit: 522766aa23b110257d5e31128ff5a5575715e880
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-04-14T09:25:58+03:00
summary:

gh-71339: Use new assertion methods in the email tests (GH-129055)

files:
M Lib/test/test_email/test_contentmanager.py
M Lib/test/test_email/test_defect_handling.py
M Lib/test/test_email/test_email.py
M Lib/test/test_mailbox.py
M Lib/test/test_poplib.py

diff --git a/Lib/test/test_email/test_contentmanager.py 
b/Lib/test/test_email/test_contentmanager.py
index 694cef4ba7e413..dceb54f15e48f4 100644
--- a/Lib/test/test_email/test_contentmanager.py
+++ b/Lib/test/test_email/test_contentmanager.py
@@ -288,7 +288,7 @@ def 
test_get_message_non_rfc822_or_external_body_yields_bytes(self):
 
 The real body is in another message.
 """))
-self.assertEqual(raw_data_manager.get_content(m)[:10], b'To: foo@ex')
+self.assertStartsWith(raw_data_manager.get_content(m), b'To: foo@ex')
 
 def test_set_text_plain(self):
 m = self._make_message()
diff --git a/Lib/test/test_email/test_defect_handling.py 
b/Lib/test/test_email/test_defect_handling.py
index 781f657418220c..44e76c8ce5e03a 100644
--- a/Lib/test/test_email/test_defect_handling.py
+++ b/Lib/test/test_email/test_defect_handling.py
@@ -57,7 +57,7 @@ def test_same_boundary_inner_outer(self):
 msg = self._str_msg(source)
 if self.raise_expected: return
 inner = msg.get_payload(0)
-self.assertTrue(hasattr(inner, 'defects'))
+self.assertHasAttr(inner, 'defects')
 self.assertEqual(len(self.get_defects(inner)), 1)
 self.assertIsInstance(self.get_defects(inner)[0],
   errors.StartBoundaryNotFoundDefect)
@@ -151,7 +151,7 @@ def test_lying_multipart(self):
 with self._raise_point(errors.NoBoundaryInMultipartDefect):
 msg = self._str_msg(source)
 if self.raise_expected: return
-self.assertTrue(hasattr(msg, 'defects'))
+self.assertHasAttr(msg, 'defects')
 self.assertEqual(len(self.get_defects(msg)), 2)
 self.assertIsInstance(self.get_defects(msg)[0],
   errors.NoBoundaryInMultipartDefect)
diff --git a/Lib/test/test_email/test_email.py 
b/Lib/test/test_email/test_email.py
index 724af3b787d38b..7b14305f997e5d 100644
--- a/Lib/test/test_email/test_email.py
+++ b/Lib/test/test_email/test_email.py
@@ -210,8 +210,8 @@ def test_make_boundary(self):
 self.assertEqual(msg.items()[0][1], 'multipart/form-data')
 # Trigger creation of boundary
 msg.as_string()
-self.assertEqual(msg.items()[0][1][:33],
-'multipart/form-data; boundary="==')
+self.assertStartsWith(msg.items()[0][1],
+  'multipart/form-data; boundary="==')
 # XXX: there ought to be tests of the uniqueness of the boundary, too.
 
 def test_message_rfc822_only(self):
@@ -303,7 +303,7 @@ def test_as_string(self):
 self.assertEqual(text, str(msg))
 fullrepr = msg.as_string(unixfrom=True)
 lines = fullrepr.split('\n')
-self.assertTrue(lines[0].startswith('From '))
+self.assertStartsWith(lines[0], 'From ')
 self.assertEqual(text, NL.join(lines[1:]))
 
 def test_as_string_policy(self):
@@ -372,7 +372,7 @@ def test_as_bytes(self):
 self.assertEqual(data, bytes(msg))
 fullrepr = msg.as_bytes(unixfrom=True)
 lines = fullrepr.split(b'\n')
-self.assertTrue(lines[0].startswith(b'From '))
+self.assertStartsWith(lines[0], b'From ')
 self.assertEqual(data, b'\n'.join(lines[1:]))
 
 def test_as_bytes_policy(self):
@@ -2228,7 +2228,7 @@ def test_same_boundary_inner_outer(self):
 msg = self._msgobj('msg_15.txt')
 # XXX We can probably eventually do better
 inner = msg.get_payload(0)
-self.assertTrue(hasattr(inner, 'defects'))
+self.assertHasAttr(inner, 'defects')
 self.assertEqual(len(inner.defects), 1)
 self.assertIsInstance(inner.defects[0],
   errors.StartBoundaryNotFoundDefect)
@@ -2340,7 +2340,7 @@ def test_no_separating_blank_line(self):
 # test_defect_handling
 def test_lying_multipart(self):
 msg = self._msgobj('msg_41.txt')
-self.assertTrue(hasattr(msg, 'defects'))
+self.assertHasAttr(msg, 'defects')
 self.assertEqual(len(msg.defects), 2)
 self.assertIsInstance(msg.defects[0],
   errors.NoBoundaryInMultipartDefect)
@@ -3684,9 +3684,7 @@ def test_make_msgid_idstring(self):
 def test_make_msgid_default_domain(self):
 with patch('socket.getfqdn') as mock_getfqdn:
 mock_getfqdn.return_value = domain = 'pythontest.example.com'
-self.assertTrue(
-email.utils.make_msgid().

[Python-checkins] gh-120144: Refactor bdb monitoring backend to match settrace behavior (#132484)

2025-04-13 Thread gaogaotiantian
https://github.com/python/cpython/commit/084d6dc122c761b90cba620eac2f25dc1660b7f1
commit: 084d6dc122c761b90cba620eac2f25dc1660b7f1
branch: main
author: Tian Gao 
committer: gaogaotiantian 
date: 2025-04-13T17:49:35-04:00
summary:

gh-120144: Refactor bdb monitoring backend to match settrace behavior (#132484)

files:
M Lib/bdb.py

diff --git a/Lib/bdb.py b/Lib/bdb.py
index ba5cacc2a54cbc..17f79aee41fdef 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -62,8 +62,7 @@ def start_trace(self, tracefunc):
 sys.monitoring.register_callback(self._tool_id, event, callback)
 if event != E.INSTRUCTION:
 all_events |= event
-self.check_trace_func()
-self.check_trace_opcodes()
+self.update_local_events()
 sys.monitoring.set_events(self._tool_id, self.GLOBAL_EVENTS)
 self._enabled = True
 
@@ -74,7 +73,6 @@ def stop_trace(self):
 if curr_tool != self._name:
 return
 sys.monitoring.clear_tool_id(self._tool_id)
-self.check_trace_opcodes()
 sys.monitoring.free_tool_id(self._tool_id)
 
 def disable_current_event(self):
@@ -95,7 +93,7 @@ def wrapper(self, *args):
 frame = sys._getframe().f_back
 ret = func(self, frame, *args)
 if self._enabled and frame.f_trace:
-self.check_trace_func()
+self.update_local_events()
 if self._disable_current_event:
 return sys.monitoring.DISABLE
 else:
@@ -159,27 +157,18 @@ def opcode_callback(self, frame, code, offset):
 if frame.f_trace and frame.f_trace_opcodes:
 frame.f_trace(frame, 'opcode', None)
 
-def check_trace_opcodes(self, frame=None):
-if frame is None:
-frame = sys._getframe().f_back
-while frame is not None:
-self.set_trace_opcodes(frame, frame.f_trace_opcodes)
-frame = frame.f_back
-
-def set_trace_opcodes(self, frame, trace_opcodes):
+def update_local_events(self, frame=None):
 if sys.monitoring.get_tool(self._tool_id) != self._name:
 return
-if trace_opcodes:
-sys.monitoring.set_local_events(self._tool_id, frame.f_code, 
E.INSTRUCTION)
-else:
-sys.monitoring.set_local_events(self._tool_id, frame.f_code, 0)
-
-def check_trace_func(self, frame=None):
 if frame is None:
 frame = sys._getframe().f_back
 while frame is not None:
 if frame.f_trace is not None:
-sys.monitoring.set_local_events(self._tool_id, frame.f_code, 
self.LOCAL_EVENTS)
+if frame.f_trace_opcodes:
+events = self.LOCAL_EVENTS | E.INSTRUCTION
+else:
+events = self.LOCAL_EVENTS
+sys.monitoring.set_local_events(self._tool_id, frame.f_code, 
events)
 frame = frame.f_back
 
 def _get_lineno(self, code, offset):
@@ -544,11 +533,11 @@ def _set_trace_opcodes(self, trace_opcodes):
 frame = self.enterframe
 while frame is not None:
 frame.f_trace_opcodes = trace_opcodes
-if self.monitoring_tracer:
-self.monitoring_tracer.set_trace_opcodes(frame, 
trace_opcodes)
 if frame is self.botframe:
 break
 frame = frame.f_back
+if self.monitoring_tracer:
+self.monitoring_tracer.update_local_events()
 
 def _set_stopinfo(self, stopframe, returnframe, stoplineno=0, 
opcode=False):
 """Set the attributes for stopping.
@@ -642,8 +631,8 @@ def set_continue(self):
 frame = frame.f_back
 for frame, (trace_lines, trace_opcodes) in 
self.frame_trace_lines_opcodes.items():
 frame.f_trace_lines, frame.f_trace_opcodes = trace_lines, 
trace_opcodes
-if self.backend == 'monitoring':
-self.monitoring_tracer.set_trace_opcodes(frame, 
trace_opcodes)
+if self.backend == 'monitoring':
+self.monitoring_tracer.update_local_events()
 self.frame_trace_lines_opcodes = {}
 
 def set_quit(self):

___
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-132388: fix typos in `Lib/test/test_hmac.py` (#132480)

2025-04-13 Thread picnixz
https://github.com/python/cpython/commit/a1cd4ca7f46eafe61dc7f26692896a4a95c7e947
commit: a1cd4ca7f46eafe61dc7f26692896a4a95c7e947
branch: main
author: abhi-jha 
committer: picnixz <[email protected]>
date: 2025-04-13T22:26:58Z
summary:

gh-132388: fix typos in `Lib/test/test_hmac.py` (#132480)

Fix typos that slipped in GH-132389 (commit 
9634085af3670b1eb654e3c7820aca66f358f39f).

files:
M Lib/test/test_hmac.py

diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py
index 3055a036c811b6..8370ba30601fae 100644
--- a/Lib/test/test_hmac.py
+++ b/Lib/test/test_hmac.py
@@ -1453,7 +1453,7 @@ def test_with_fallback(self):
 cache.pop('foo')
 
 
-class BuiiltinMiscellaneousTests(BuiltinModuleMixin, unittest.TestCase):
+class BuiltinMiscellaneousTests(BuiltinModuleMixin, unittest.TestCase):
 """HMAC-BLAKE2 is not standardized as BLAKE2 is a keyed hash function.
 
 In particular, there is no official test vectors for HMAC-BLAKE2.
@@ -1464,9 +1464,9 @@ class BuiiltinMiscellaneousTests(BuiltinModuleMixin, 
unittest.TestCase):
 @classmethod
 def setUpClass(cls):
 super().setUpClass()
-cls.blake2 = blake2 = import_module("_blake2")
-cls.blake2b = blake2.blake2b
-cls.blake2s = blake2.blake2s
+cls.blake2 = import_module("_blake2")
+cls.blake2b = cls.blake2.blake2b
+cls.blake2s = cls.blake2.blake2s
 
 def assert_hmac_blake_correctness(self, digest, key, msg, hashfunc):
 self.assertIsInstance(digest, bytes)

___
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-132099: Harmonize Bluetooth address handling (GH-132486)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/1fc1df8dcc7a853b0649bc8df37cd07cbd2b6230
commit: 1fc1df8dcc7a853b0649bc8df37cd07cbd2b6230
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-04-14T08:58:56+03:00
summary:

gh-132099: Harmonize Bluetooth address handling (GH-132486)

Now all protocols always accept the Bluetooth address as string and
getsockname() always returns the Bluetooth address as string.

* BTPROTO_SCO now accepts not only bytes, but str.
* BTPROTO_SCO now checks address for embedded null.
* On *BSD, BTPROTO_HCI now accepts str instead of bytes.
* On FreeBSD, getsockname() for BTPROTO_HCI now returns str instead of bytes.
* On NetBSD and DragonFly BDS, BTPROTO_HCI now checks address for embedded null.

files:
M Doc/library/socket.rst
M Lib/test/test_socket.py
M Modules/socketmodule.c

diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index 2e38101c01d89d..11f7f06c59e873 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -158,9 +158,8 @@ created.  Socket addresses are represented as follows:
 
 - On Linux it accepts a tuple ``(device_id,)`` where ``device_id``
   is an integer specifying the number of the Bluetooth device.
-- On FreeBSD, NetBSD and DragonFly BSD it accepts ``bdaddr`` where 
``bdaddr``
-  is a :class:`bytes` object containing the Bluetooth address in a
-  string format. (ex. ``b'12:23:34:45:56:67'``)
+- On FreeBSD, NetBSD and DragonFly BSD it accepts ``bdaddr``
+  where ``bdaddr`` is the Bluetooth address as a string.
 
 .. versionchanged:: 3.2
NetBSD and DragonFlyBSD support added.
@@ -168,9 +167,9 @@ created.  Socket addresses are represented as follows:
 .. versionchanged:: 3.13.3
FreeBSD support added.
 
-  - :const:`BTPROTO_SCO` accepts ``bdaddr`` where ``bdaddr`` is a
-:class:`bytes` object containing the Bluetooth address in a
-string format. (ex. ``b'12:23:34:45:56:67'``)
+  - :const:`BTPROTO_SCO` accepts ``bdaddr`` where ``bdaddr`` is
+the Bluetooth address as a string or a :class:`bytes` object.
+(ex. ``'12:23:34:45:56:67'`` or ``b'12:23:34:45:56:67'``)
 
 .. versionchanged:: next
FreeBSD support added.
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 66cb63daca02ae..93dbcc981591ca 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -2681,6 +2681,8 @@ def testBadL2capAddr(self):
 f.bind(socket.BDADDR_ANY)
 with self.assertRaises(OSError):
 f.bind((socket.BDADDR_ANY.encode(), 0x1001))
+with self.assertRaises(OSError):
+f.bind(('\ud812', 0x1001))
 
 def testBindRfcommSocket(self):
 with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, 
socket.BTPROTO_RFCOMM) as s:
@@ -2712,6 +2714,8 @@ def testBadRfcommAddr(self):
 s.bind((socket.BDADDR_ANY, channel, 0))
 with self.assertRaises(OSError):
 s.bind((socket.BDADDR_ANY + '\0', channel))
+with self.assertRaises(OSError):
+s.bind('\ud812')
 with self.assertRaises(OSError):
 s.bind(('invalid', channel))
 
@@ -2719,7 +2723,7 @@ def testBadRfcommAddr(self):
 def testBindHciSocket(self):
 with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, 
socket.BTPROTO_HCI) as s:
 if sys.platform.startswith(('netbsd', 'dragonfly', 'freebsd')):
-s.bind(socket.BDADDR_ANY.encode())
+s.bind(socket.BDADDR_ANY)
 addr = s.getsockname()
 self.assertEqual(addr, socket.BDADDR_ANY)
 else:
@@ -2738,14 +2742,17 @@ def testBadHciAddr(self):
 with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, 
socket.BTPROTO_HCI) as s:
 if sys.platform.startswith(('netbsd', 'dragonfly', 'freebsd')):
 with self.assertRaises(OSError):
-s.bind(socket.BDADDR_ANY)
+s.bind(socket.BDADDR_ANY.encode())
 with self.assertRaises(OSError):
-s.bind((socket.BDADDR_ANY.encode(),))
-if sys.platform.startswith('freebsd'):
-with self.assertRaises(ValueError):
-s.bind(socket.BDADDR_ANY.encode() + b'\0')
-with self.assertRaises(ValueError):
-s.bind(socket.BDADDR_ANY.encode() + b' '*100)
+s.bind((socket.BDADDR_ANY,))
+with self.assertRaises(OSError):
+s.bind(socket.BDADDR_ANY + '\0')
+with self.assertRaises((ValueError, OSError)):
+s.bind(socket.BDADDR_ANY + ' '*100)
+with self.assertRaises(OSError):
+s.bind('\ud812')
+with self.assertRaises(OSError):
+s.bind('invalid')
 with self.assertRaises(OSError):
 s.bind(b'invalid')

[Python-checkins] GH-115322: Add missing audit hooks (GH-115624)

2025-04-13 Thread gpshead
https://github.com/python/cpython/commit/2666a06d336675247e1602aeb64170b2443602ce
commit: 2666a06d336675247e1602aeb64170b2443602ce
branch: main
author: Robin Jadoul 
committer: gpshead 
date: 2025-04-13T21:46:20Z
summary:

GH-115322: Add missing audit hooks (GH-115624)

Add extra audit hooks to catch C function calling from ctypes,
reading/writing files through readline and executing external
programs through _posixsubprocess.

* Make audit-tests for open pass when readline.append_history_file is 
unavailable
* Less direct testing of _posixsubprocess for audit hooks
* Also remove the audit hook from call_cdeclfunction now that _ctypes_callproc 
does it instead.
* reword the NEWS entry.
* mention readline in NEWS
* add versionchanged markers
* fix audit_events.rst versionadded
* doc lint

-

Co-authored-by: Gregory P. Smith 

files:
A Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst
M Doc/library/audit_events.rst
M Doc/library/ctypes.rst
M Doc/library/readline.rst
M Lib/test/audit-tests.py
M Lib/test/test_audit.py
M Modules/_ctypes/callproc.c
M Modules/_posixsubprocess.c
M Modules/readline.c

diff --git a/Doc/library/audit_events.rst b/Doc/library/audit_events.rst
index a2a90a00d0cfca..d2377a38d78c81 100644
--- a/Doc/library/audit_events.rst
+++ b/Doc/library/audit_events.rst
@@ -23,25 +23,30 @@ information on handling these events.
 The following events are raised internally and do not correspond to any
 public API of CPython:
 
-+--+---+
-| Audit event  | Arguments |
-+==+===+
-| _winapi.CreateFile   | ``file_name``, ``desired_access``,|
-|  | ``share_mode``, ``creation_disposition``, |
-|  | ``flags_and_attributes``  |
-+--+---+
-| _winapi.CreateJunction   | ``src_path``, ``dst_path``|
-+--+---+
-| _winapi.CreateNamedPipe  | ``name``, ``open_mode``, ``pipe_mode``|
-+--+---+
-| _winapi.CreatePipe   |   |
-+--+---+
-| _winapi.CreateProcess| ``application_name``, ``command_line``,   |
-|  | ``current_directory`` |
-+--+---+
-| _winapi.OpenProcess  | ``process_id``, ``desired_access``|
-+--+---+
-| _winapi.TerminateProcess | ``handle``, ``exit_code`` |
-+--+---+
-| ctypes.PyObj_FromPtr | ``obj``   |
-+--+---+
+++---+
+| Audit event| Arguments |
+++===+
+| _winapi.CreateFile | ``file_name``, ``desired_access``,|
+|| ``share_mode``, ``creation_disposition``, |
+|| ``flags_and_attributes``  |
+++---+
+| _winapi.CreateJunction | ``src_path``, ``dst_path``|
+++---+
+| _winapi.CreateNamedPipe| ``name``, ``open_mode``, ``pipe_mode``|
+++---+
+| _winapi.CreatePipe |   |
+++---+
+| _winapi.CreateProcess  | ``application_name``, ``command_line``,   |
+|| ``current_directory`` |
+++---+
+| _winapi.OpenProcess| ``process_id``, ``desired_access``|
+++---+
+| _winapi.TerminateProcess   | ``handle``, ``exit_code`` |
+++---+
+| _posixsubprocess.fork_exec | ``exec_list``, ``args``, ``env``  |
+++---+
+| ctypes.PyObj_FromPtr   | ``obj``   |
+++---+
+
+.. versionadded:: next
+   The ``_posixsubprocess.fork_exec

[Python-checkins] [3.13] gh-101100: Fix sphinx warnings in `library/plistlib.rst` (GH-132422) (#132485)

2025-04-13 Thread hugovk
https://github.com/python/cpython/commit/f206b98c18a3467477058ae5b5cad54e84f37f13
commit: f206b98c18a3467477058ae5b5cad54e84f37f13
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: hugovk <[email protected]>
date: 2025-04-13T18:41:56Z
summary:

[3.13] gh-101100: Fix sphinx warnings in `library/plistlib.rst` (GH-132422) 
(#132485)

Co-authored-by: Yuki Kobayashi 

files:
M Doc/library/plistlib.rst
M Doc/tools/.nitignore

diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst
index c3a133e46a64d6..415c4b45c4f100 100644
--- a/Doc/library/plistlib.rst
+++ b/Doc/library/plistlib.rst
@@ -147,8 +147,9 @@ The following classes are available:
Wraps an :class:`int`.  This is used when reading or writing NSKeyedArchiver
encoded data, which contains UID (see PList manual).
 
-   It has one attribute, :attr:`data`, which can be used to retrieve the int 
value
-   of the UID.  :attr:`data` must be in the range ``0 <= data < 2**64``.
+   .. attribute:: data
+
+  Int value of the UID.  It must be in the range ``0 <= data < 2**64``.
 
.. versionadded:: 3.8
 
diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index 3e56c939e5b2cf..191287d02c79fe 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -33,7 +33,6 @@ Doc/library/optparse.rst
 Doc/library/os.rst
 Doc/library/pickletools.rst
 Doc/library/platform.rst
-Doc/library/plistlib.rst
 Doc/library/profile.rst
 Doc/library/pyexpat.rst
 Doc/library/resource.rst

___
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-132064: Make annotationlib use __annotate__ if only it is present (#132195)

2025-04-13 Thread JelleZijlstra
https://github.com/python/cpython/commit/4d3ad0467e5cb145b1f4bde4be5eb776946a4269
commit: 4d3ad0467e5cb145b1f4bde4be5eb776946a4269
branch: main
author: Jelle Zijlstra 
committer: JelleZijlstra 
date: 2025-04-13T16:32:44-07:00
summary:

gh-132064: Make annotationlib use __annotate__ if only it is present (#132195)

files:
A Misc/NEWS.d/next/Library/2025-04-06-21-17-14.gh-issue-132064.ktPwDM.rst
M Doc/library/annotationlib.rst
M Lib/annotationlib.py
M Lib/test/test_annotationlib.py
M Lib/test/test_functools.py

diff --git a/Doc/library/annotationlib.rst b/Doc/library/annotationlib.rst
index 140e1aa12e2938..7a6d44069ed005 100644
--- a/Doc/library/annotationlib.rst
+++ b/Doc/library/annotationlib.rst
@@ -317,11 +317,22 @@ Functions
Compute the annotations dict for an object.
 
*obj* may be a callable, class, module, or other object with
-   :attr:`~object.__annotate__` and :attr:`~object.__annotations__` attributes.
-   Passing in an object of any other type raises :exc:`TypeError`.
+   :attr:`~object.__annotate__` or :attr:`~object.__annotations__` attributes.
+   Passing any other object raises :exc:`TypeError`.
 
The *format* parameter controls the format in which annotations are 
returned,
and must be a member of the :class:`Format` enum or its integer equivalent.
+   The different formats work as follows:
+
+   * VALUE: :attr:`!object.__annotations__` is tried first; if that does not 
exist,
+ the :attr:`!object.__annotate__` function is called if it exists.
+   * FORWARDREF: If :attr:`!object.__annotations__` exists and can be 
evaluated successfully,
+ it is used; otherwise, the :attr:`!object.__annotate__` function is 
called. If it
+ does not exist either, :attr:`!object.__annotations__` is tried again and 
any error
+ from accessing it is re-raised.
+   * STRING: If :attr:`!object.__annotate__` exists, it is called first;
+ otherwise, :attr:`!object.__annotations__` is used and stringified
+ using :func:`annotations_to_string`.
 
Returns a dict. :func:`!get_annotations` returns a new dict every time
it's called; calling it twice on the same object will return two
diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py
index 237b3470b831fd..e1c96298426283 100644
--- a/Lib/annotationlib.py
+++ b/Lib/annotationlib.py
@@ -640,12 +640,18 @@ def get_annotations(
 ):
 """Compute the annotations dict for an object.
 
-obj may be a callable, class, or module.
-Passing in an object of any other type raises TypeError.
-
-Returns a dict.  get_annotations() returns a new dict every time
-it's called; calling it twice on the same object will return two
-different but equivalent dicts.
+obj may be a callable, class, module, or other object with
+__annotate__ or __annotations__ attributes.
+Passing any other object raises TypeError.
+
+The *format* parameter controls the format in which annotations are 
returned,
+and must be a member of the Format enum or its integer equivalent.
+For the VALUE format, the __annotations__ is tried first; if it
+does not exist, the __annotate__ function is called. The
+FORWARDREF format uses __annotations__ if it exists and can be
+evaluated, and otherwise falls back to calling the __annotate__ function.
+The SOURCE format tries __annotate__ first, and falls back to
+using __annotations__, stringified using annotations_to_string().
 
 This function handles several details for you:
 
@@ -687,24 +693,29 @@ def get_annotations(
 
 match format:
 case Format.VALUE:
-# For VALUE, we only look at __annotations__
+# For VALUE, we first look at __annotations__
 ann = _get_dunder_annotations(obj)
+
+# If it's not there, try __annotate__ instead
+if ann is None:
+ann = _get_and_call_annotate(obj, format)
 case Format.FORWARDREF:
 # For FORWARDREF, we use __annotations__ if it exists
 try:
-return dict(_get_dunder_annotations(obj))
+ann = _get_dunder_annotations(obj)
 except NameError:
 pass
+else:
+if ann is not None:
+return dict(ann)
 
 # But if __annotations__ threw a NameError, we try calling 
__annotate__
 ann = _get_and_call_annotate(obj, format)
-if ann is not None:
-return ann
-
-# If that didn't work either, we have a very weird object: 
evaluating
-# __annotations__ threw NameError and there is no __annotate__. In 
that case,
-# we fall back to trying __annotations__ again.
-return dict(_get_dunder_annotations(obj))
+if ann is None:
+# If that didn't work either, we have a very weird object: 
evaluating
+# __annotations__ threw NameError and there is no 
__annotate__. In that case,
+#

[Python-checkins] gh-132435: Test syntax warnings in a finally block (GH-132436)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/887eabc5a74316708460120d60d0fa4f8bdf5960
commit: 887eabc5a74316708460120d60d0fa4f8bdf5960
branch: main
author: Tomas R. 
committer: serhiy-storchaka 
date: 2025-04-13T20:44:00Z
summary:

gh-132435: Test syntax warnings in a finally block (GH-132436)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-04-13-10-34-27.gh-issue-131927.otp80n.rst
M Lib/test/test_compile.py

diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 0377b3f954f44b..57e5f29b015637 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1664,6 +1664,26 @@ def test_compile_warnings(self):
 
 self.assertEqual(len(caught), 2)
 
+def test_compile_warning_in_finally(self):
+# Ensure that warnings inside finally blocks are
+# only emitted once despite the block being
+# compiled twice (for normal execution and for
+# exception handling).
+source = textwrap.dedent("""
+try:
+pass
+finally:
+1 is 1
+""")
+
+with warnings.catch_warnings(record=True) as caught:
+warnings.simplefilter("default")
+compile(source, '', 'exec')
+
+self.assertEqual(len(caught), 1)
+self.assertEqual(caught[0].category, SyntaxWarning)
+self.assertIn("\"is\" with 'int' literal", str(caught[0].message))
+
 class TestBooleanExpression(unittest.TestCase):
 class Value:
 def __init__(self):
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-13-10-34-27.gh-issue-131927.otp80n.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-13-10-34-27.gh-issue-131927.otp80n.rst
new file mode 100644
index 00..9aa940a10daa69
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-13-10-34-27.gh-issue-131927.otp80n.rst
@@ -0,0 +1,3 @@
+Compiler warnings originating from the same module and line number are now
+only emitted once, matching the behaviour of warnings emitted from user
+code. This can also be configured with :mod:`warnings` filters.

___
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-101100: Fix sphinx warnings in `library/plistlib.rst` (#132422)

2025-04-13 Thread hugovk
https://github.com/python/cpython/commit/fc7e4e7bbd5d459b76b96991413569a5b7889fbe
commit: fc7e4e7bbd5d459b76b96991413569a5b7889fbe
branch: main
author: Yuki Kobayashi 
committer: hugovk <[email protected]>
date: 2025-04-13T18:35:26Z
summary:

gh-101100: Fix sphinx warnings in `library/plistlib.rst` (#132422)

files:
M Doc/library/plistlib.rst
M Doc/tools/.nitignore

diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst
index c3a133e46a64d6..415c4b45c4f100 100644
--- a/Doc/library/plistlib.rst
+++ b/Doc/library/plistlib.rst
@@ -147,8 +147,9 @@ The following classes are available:
Wraps an :class:`int`.  This is used when reading or writing NSKeyedArchiver
encoded data, which contains UID (see PList manual).
 
-   It has one attribute, :attr:`data`, which can be used to retrieve the int 
value
-   of the UID.  :attr:`data` must be in the range ``0 <= data < 2**64``.
+   .. attribute:: data
+
+  Int value of the UID.  It must be in the range ``0 <= data < 2**64``.
 
.. versionadded:: 3.8
 
diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index f43dba19d1340c..926d2cd42bdf02 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -32,7 +32,6 @@ Doc/library/optparse.rst
 Doc/library/os.rst
 Doc/library/pickletools.rst
 Doc/library/platform.rst
-Doc/library/plistlib.rst
 Doc/library/profile.rst
 Doc/library/pyexpat.rst
 Doc/library/resource.rst

___
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-86513: improve docs of loop.call_exception_handler (#132466)

2025-04-13 Thread kumaraditya303
https://github.com/python/cpython/commit/ce753517a87eec776c176f3245ce5d1554a59341
commit: ce753517a87eec776c176f3245ce5d1554a59341
branch: main
author: Kumar Aditya 
committer: kumaraditya303 
date: 2025-04-13T21:39:24Z
summary:

gh-86513: improve docs of loop.call_exception_handler (#132466)

files:
M Doc/library/asyncio-eventloop.rst
M Lib/asyncio/base_events.py

diff --git a/Doc/library/asyncio-eventloop.rst 
b/Doc/library/asyncio-eventloop.rst
index fae68803107639..8f561744fe4981 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -1440,6 +1440,8 @@ Allows customizing how exceptions are handled in the 
event loop.
* 'protocol' (optional): :ref:`Protocol ` instance;
* 'transport' (optional): :ref:`Transport ` instance;
* 'socket' (optional): :class:`socket.socket` instance;
+   * 'source_traceback' (optional): Traceback of the source;
+   * 'handle_traceback' (optional): Traceback of the handle;
* 'asyncgen' (optional): Asynchronous generator that caused
 the exception.
 
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 7b4e92aed682d5..29b872ce00ec81 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -1879,6 +1879,8 @@ def call_exception_handler(self, context):
 - 'protocol' (optional): Protocol instance;
 - 'transport' (optional): Transport instance;
 - 'socket' (optional): Socket instance;
+- 'source_traceback' (optional): Traceback of the source;
+- 'handle_traceback' (optional): Traceback of the handle;
 - 'asyncgen' (optional): Asynchronous generator that caused
  the exception.
 

___
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-131927: Prevent emitting compiler warnings twice (GH-131993) (GH-132463)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/4ff5d88fb1416d347bfd8bb53b0945adadc924ef
commit: 4ff5d88fb1416d347bfd8bb53b0945adadc924ef
branch: 3.13
author: Tomas R. 
committer: serhiy-storchaka 
date: 2025-04-13T08:42:04Z
summary:

[3.13] gh-131927: Prevent emitting compiler warnings twice (GH-131993) 
(GH-132463)

(cherry picked from commit 3d08c8ad20dfabd4864be139cd9c2eb5602ccdfe)

files:
M Include/cpython/warnings.h
M Lib/test/test_compile.py
M Python/_warnings.c
M Python/compile.c

diff --git a/Include/cpython/warnings.h b/Include/cpython/warnings.h
index 4e3eb88e8ff447..8731fd2e96b716 100644
--- a/Include/cpython/warnings.h
+++ b/Include/cpython/warnings.h
@@ -18,3 +18,9 @@ PyAPI_FUNC(int) PyErr_WarnExplicitFormat(
 
 // DEPRECATED: Use PyErr_WarnEx() instead.
 #define PyErr_Warn(category, msg) PyErr_WarnEx((category), (msg), 1)
+
+int _PyErr_WarnExplicitObjectWithContext(
+PyObject *category,
+PyObject *message,
+PyObject *filename,
+int lineno);
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index ed4e6265eac438..b57adfadb5af5f 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1512,6 +1512,24 @@ async def name_4():
 pass
 [[]]
 
+def test_compile_warnings(self):
+# See gh-131927
+# Compile warnings originating from the same file and
+# line are now only emitted once.
+with warnings.catch_warnings(record=True) as caught:
+warnings.simplefilter("default")
+compile('1 is 1', '', 'eval')
+compile('1 is 1', '', 'eval')
+
+self.assertEqual(len(caught), 1)
+
+with warnings.catch_warnings(record=True) as caught:
+warnings.simplefilter("always")
+compile('1 is 1', '', 'eval')
+compile('1 is 1', '', 'eval')
+
+self.assertEqual(len(caught), 2)
+
 @requires_debug_ranges()
 class TestSourcePositions(unittest.TestCase):
 # Ensure that compiled code snippets have correct line and column numbers
diff --git a/Python/_warnings.c b/Python/_warnings.c
index 4bb83b214ae6cc..5bbd4a9c19f6c9 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -1317,6 +1317,28 @@ PyErr_WarnExplicitObject(PyObject *category, PyObject 
*message,
 return 0;
 }
 
+/* Like PyErr_WarnExplicitObject, but automatically sets up context */
+int
+_PyErr_WarnExplicitObjectWithContext(PyObject *category, PyObject *message,
+ PyObject *filename, int lineno)
+{
+PyObject *unused_filename, *module, *registry;
+int unused_lineno;
+int stack_level = 1;
+
+if (!setup_context(stack_level, NULL, &unused_filename, &unused_lineno,
+   &module, ®istry)) {
+return -1;
+}
+
+int rc = PyErr_WarnExplicitObject(category, message, filename, lineno,
+  module, registry);
+Py_DECREF(unused_filename);
+Py_DECREF(registry);
+Py_DECREF(module);
+return rc;
+}
+
 int
 PyErr_WarnExplicit(PyObject *category, const char *text,
const char *filename_str, int lineno,
diff --git a/Python/compile.c b/Python/compile.c
index ba780927eff9d6..bb2c2293a38c9a 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -6616,8 +6616,8 @@ compiler_warn(struct compiler *c, location loc,
 if (msg == NULL) {
 return ERROR;
 }
-if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename,
- loc.lineno, NULL, NULL) < 0)
+if (_PyErr_WarnExplicitObjectWithContext(PyExc_SyntaxWarning, msg,
+ c->c_filename, loc.lineno) < 0)
 {
 if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
 /* Replace the SyntaxWarning exception with a SyntaxError

___
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] Docs: Fix a typo in `Doc/c-api/unicode.rst` (#132318)

2025-04-13 Thread picnixz
https://github.com/python/cpython/commit/03b18e0d8cebdf4bef85cbfbfcb2cb4d25ac5241
commit: 03b18e0d8cebdf4bef85cbfbfcb2cb4d25ac5241
branch: main
author: Yongzi Li <[email protected]>
committer: picnixz <[email protected]>
date: 2025-04-13T07:16:59Z
summary:

Docs: Fix a typo in `Doc/c-api/unicode.rst` (#132318)

files:
M Doc/c-api/unicode.rst

diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 31063962ae51c5..e07121f17d9c29 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -622,7 +622,7 @@ APIs:
 
On error, set *\*p_left* to ``NULL`` and set an exception.
 
-   On sucess, set *\*p_left* to a new strong reference to the result.
+   On success, set *\*p_left* to a new strong reference to the result.
 
 
 .. c:function:: void PyUnicode_AppendAndDel(PyObject **p_left, PyObject *right)

___
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] Fix a typo in c-api/typeobj.rst (#132317)

2025-04-13 Thread AA-Turner
https://github.com/python/cpython/commit/f69b344e0944bd8d59d2dc4d98e988cc4dbfadf3
commit: f69b344e0944bd8d59d2dc4d98e988cc4dbfadf3
branch: main
author: Yongzi Li <[email protected]>
committer: AA-Turner <[email protected]>
date: 2025-04-13T07:18:58Z
summary:

Fix a typo in c-api/typeobj.rst (#132317)

files:
M Doc/c-api/typeobj.rst

diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 6d2201d02f685d..3b9f07778d5ace 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -611,7 +611,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
Note that the :c:member:`~PyVarObject.ob_size` field may later be used for
other purposes. For example, :py:type:`int` instances use the bits of
:c:member:`~PyVarObject.ob_size` in an implementation-defined
-   way; the underlying storage and its size should be acessed using
+   way; the underlying storage and its size should be accessed using
:c:func:`PyLong_Export`.
 
.. note::

___
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] Fix a typo in c-api/typeobj.rst (GH-132317) (#132464)

2025-04-13 Thread picnixz
https://github.com/python/cpython/commit/244a64244396cb1c5c04323471a22157b839ef14
commit: 244a64244396cb1c5c04323471a22157b839ef14
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: picnixz <[email protected]>
date: 2025-04-13T07:24:46Z
summary:

[3.13] Fix a typo in c-api/typeobj.rst (GH-132317) (#132464)

Fix a typo in c-api/typeobj.rst (GH-132317)
(cherry picked from commit f69b344e0944bd8d59d2dc4d98e988cc4dbfadf3)

Co-authored-by: Yongzi Li <[email protected]>

files:
M Doc/c-api/typeobj.rst

diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index f531e326862a17..93c377c54bc73b 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -611,7 +611,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
Note that the :c:member:`~PyVarObject.ob_size` field may later be used for
other purposes. For example, :py:type:`int` instances use the bits of
:c:member:`~PyVarObject.ob_size` in an implementation-defined
-   way; the underlying storage and its size should be acessed using
+   way; the underlying storage and its size should be accessed using
:c:func:`PyLong_Export`.
 
.. note::

___
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-132354: document return value for `asyncio.Task.cancel` (#132374)

2025-04-13 Thread kumaraditya303
https://github.com/python/cpython/commit/64b066ad298506f715647c9a2524c9fbbc764cc2
commit: 64b066ad298506f715647c9a2524c9fbbc764cc2
branch: main
author: Felix Scherz 
committer: kumaraditya303 
date: 2025-04-13T13:05:44+05:30
summary:

gh-132354: document return value for `asyncio.Task.cancel` (#132374)

files:
M Doc/library/asyncio-task.rst
M Misc/ACKS

diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index b6ae443860843b..59acce1990ae04 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -1381,7 +1381,10 @@ Task Object
 
   Request the Task to be cancelled.
 
-  This arranges for a :exc:`CancelledError` exception to be thrown
+  If the Task is already *done* or *cancelled*, return ``False``,
+  otherwise, return ``True``.
+
+  The method arranges for a :exc:`CancelledError` exception to be thrown
   into the wrapped coroutine on the next cycle of the event loop.
 
   The coroutine then has a chance to clean up or even deny the
diff --git a/Misc/ACKS b/Misc/ACKS
index c3e8530d5b36c2..25542d01de695c 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1663,6 +1663,7 @@ Andreas Schawo
 Neil Schemenauer
 David Scherer
 Wolfgang Scherer
+Felix Scherz
 Hynek Schlawack
 Bob Schmertz
 Gregor Schmid

___
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-132106: Ensure that running `logging.handlers.QueueListener` cannot be started again (GH-132444)

2025-04-13 Thread vsajip
https://github.com/python/cpython/commit/5863cd70b8782313b52bb8c71a4127d7ea4c50e9
commit: 5863cd70b8782313b52bb8c71a4127d7ea4c50e9
branch: main
author: Charles Machalow 
committer: vsajip 
date: 2025-04-13T08:53:13+01:00
summary:

gh-132106: Ensure that running `logging.handlers.QueueListener` cannot be 
started again (GH-132444)

Prevents a thread leak
Co-authored-by: Bénédikt Tran <[email protected]>

files:
A Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst
M Doc/library/logging.handlers.rst
M Doc/whatsnew/3.14.rst
M Lib/logging/handlers.py
M Lib/test/test_logging.py

diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index b737fe311dfb6e..72312b512a5884 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -1186,6 +1186,10 @@ possible, while any potentially slow operations (such as 
sending an email via
   This starts up a background thread to monitor the queue for
   LogRecords to process.
 
+  .. versionchanged:: next
+ Raises :exc:`RuntimeError` if called and the listener is already
+ running.
+
.. method:: stop()
 
   Stops the listener.
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 762d53eeb2df1a..421d12660b7956 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -819,6 +819,10 @@ logging.handlers
   manager protocol, allowing it to be used in a :keyword:`with` statement.
   (Contributed by Charles Machalow in :gh:`132106`.)
 
+* :meth:`QueueListener.start ` now
+  raises a :exc:`RuntimeError` if the listener is already started.
+  (Contributed by Charles Machalow in :gh:`132106`.)
+
 
 mimetypes
 -
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 0571ed2356345a..2748b5941eade2 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -1561,6 +1561,9 @@ def start(self):
 This starts up a background thread to monitor the queue for
 LogRecords to process.
 """
+if self._thread is not None:
+raise RuntimeError("Listener already started")
+
 self._thread = t = threading.Thread(target=self._monitor)
 t.daemon = True
 t.start()
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 11f6b64abe28fb..9305844829a500 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -4356,6 +4356,17 @@ def test_queue_listener_context_manager(self):
 listener.stop()
 self.assertIsNone(listener._thread)
 
+def test_queue_listener_multi_start(self):
+handler = TestHandler(support.Matcher())
+with logging.handlers.QueueListener(self.queue, handler) as listener:
+self.assertRaises(RuntimeError, listener.start)
+
+with listener:
+self.assertRaises(RuntimeError, listener.start)
+
+listener.start()
+listener.stop()
+
 def test_queue_listener_with_StreamHandler(self):
 # Test that traceback and stack-info only appends once (bpo-34334, 
bpo-46755).
 listener = logging.handlers.QueueListener(self.queue, self.root_hdlr)
diff --git 
a/Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst 
b/Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst
new file mode 100644
index 00..b6d58a29f9b42f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-04-12-09-30-24.gh-issue-132106.OxUds3.rst
@@ -0,0 +1,2 @@
+:meth:`QueueListener.start ` now
+raises a :exc:`RuntimeError` if the listener is already started.

___
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-131624: Fix posix_spawn tests failing on NetBSD with stack limit assertions (GH-131625)

2025-04-13 Thread serhiy-storchaka
https://github.com/python/cpython/commit/c7f6535e4a3b447fbd67bf98eea82fd243e780be
commit: c7f6535e4a3b447fbd67bf98eea82fd243e780be
branch: main
author: Furkan Onder 
committer: serhiy-storchaka 
date: 2025-04-13T14:06:38+03:00
summary:

gh-131624: Fix posix_spawn tests failing on NetBSD with stack limit assertions 
(GH-131625)

Fix recursive limit assertions on NetBSD for posix_spawn.

files:
M Python/ceval.c

diff --git a/Python/ceval.c b/Python/ceval.c
index e4a63ad9287783..278d9e36045da2 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -437,7 +437,7 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
 _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + 
PYOS_STACK_MARGIN_BYTES;
 #else
 uintptr_t here_addr = _Py_get_machine_stack_pointer();
-#  if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX)
+#  if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX) && 
!defined(__NetBSD__)
 size_t stack_size, guard_size;
 void *stack_addr;
 pthread_attr_t attr;

___
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]