[Python-checkins] gh-125470: Fix warning in `Python/generated_cases.c.h` (#125471)

2024-10-14 Thread sobolevn
https://github.com/python/cpython/commit/0c8c665581ede95fe119f902b070e395614b78ed
commit: 0c8c665581ede95fe119f902b070e395614b78ed
branch: main
author: sobolevn 
committer: sobolevn 
date: 2024-10-14T23:46:17+03:00
summary:

gh-125470: Fix warning in `Python/generated_cases.c.h` (#125471)

Co-authored-by: Kirill Podoprigora 

files:
M Python/bytecodes.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h

diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index b22916aeaa248b..e6525657cabc2b 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -611,7 +611,9 @@ dummy_func(
 // specializations, but there is no output.
 // At the end we just skip over the STORE_FAST.
 op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
+#ifndef NDEBUG
 PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
+#endif
 PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
 
 int next_oparg;
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 0ed361a2ee7fb0..15a6c7bc1a7966 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -737,7 +737,9 @@
 _PyStackRef left;
 right = stack_pointer[-1];
 left = stack_pointer[-2];
+#ifndef NDEBUG
 PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
+#endif
 PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
 int next_oparg;
 #if TIER_ONE
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 7bd1b7dd5aba27..a9290986c24f45 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -183,7 +183,9 @@
 /* Skip 1 cache entry */
 // _BINARY_OP_INPLACE_ADD_UNICODE
 {
+#ifndef NDEBUG
 PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
+#endif
 PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
 int next_oparg;
 #if TIER_ONE

___
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] Fix idlelib typos (GH-125484) (#125488)

2024-10-14 Thread terryjreedy
https://github.com/python/cpython/commit/86296bbc178aa2f7094c8d7ab9eb4175f78d105f
commit: 86296bbc178aa2f7094c8d7ab9eb4175f78d105f
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: terryjreedy 
date: 2024-10-14T21:34:38Z
summary:

[3.12] Fix idlelib typos (GH-125484) (#125488)

Fix idlelib typos (GH-125484)

Propagate fixes in Doc/library/idle.rst to help.html.
Change 'interruptable' to 'interruptible' in run.py.
The latter was reported by ember91 in PR 125473.
(cherry picked from commit 3fea1d000ef0a74062fd3fe218ad94618b08d9f2)

Co-authored-by: Terry Jan Reedy 

files:
M Lib/idlelib/help.html
M Lib/idlelib/run.py

diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html
index 827d230b54e159..2a4adc6a4d395f 100644
--- a/Lib/idlelib/help.html
+++ b/Lib/idlelib/help.html
@@ -5,7 +5,7 @@
 
 
 
-IDLE — Python 3.13.0a2 documentation
+IDLE — Python 3.14.0a0 documentation
 
 
 
@@ -18,7 +18,7 @@
 
 
 
 
 
@@ -26,6 +26,7 @@
 
 
 
+
 https://docs.python.org/3/library/idle.html"; />
 
 
@@ -45,6 +46,8 @@
 
 
 
+
+
 
   
 
@@ -184,7 +187,7 @@ Navigation
 
   
 
-  3.13.0a2 Documentation »
+  3.14.0a0 Documentation »
 
 
   The Python 
Standard Library »
@@ -554,7 +557,7 @@ Key bindingsControl 
key on Windows and
-Unix and the Command key 
on macOS.  (And all such dicussions
+Unix and the Command key 
on macOS.  (And all such discussions
 assume that the keys have not been re-bound to something else.)
 
 Arrow keys move the cursor one character or line.
@@ -562,8 +565,8 @@ Key bindingsHome and End go to the beginning or end 
of the line.
 Page Up and Page Down go up or down one 
screen.
 C-Home and C-End go to beginning or end 
of the file.
-Backspace and Del (or C-d) delete 
the previous or
-next character.
+Backspace and Del (or C-d) delete the previous
+or next character.
 C-Backspace and C-Del delete one word left 
or right.
 C-k deletes (‘kills’) everything to the right.
 
@@ -694,7 +697,7 @@ Shell window
-C-c attemps to interrupt statement execution (but may 
fail).
+C-c attempts to interrupt statement execution (but may 
fail).
 C-d closes Shell if typed at a >>> 
prompt.
 Alt-p and Alt-n (C-p and C-n on macOS)
 retrieve to the current prompt the previous or next previously
@@ -1136,7 +1139,7 @@ Navigation
 
   
 
-  3.13.0a2 Documentation »
+  3.14.0a0 Documentation »
 
 
   The Python 
Standard Library »
@@ -1180,7 +1183,7 @@ Navigation
 
 
 
-Last updated on Jan 17, 2024 (06:57 UTC).
+Last updated on Oct 14, 2024 (20:27 UTC).
 Found a bug?
 
 
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index 476a7b26c004b5..2faeba678c7262 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -101,11 +101,11 @@ def handle_tk_events(tcl=tcl):
 
 # Thread shared globals: Establish a queue between a subthread (which handles
 # the socket) and the main thread (which runs user code), plus global
-# completion, exit and interruptable (the main thread) flags:
+# completion, exit and interruptible (the main thread) flags:
 
 exit_now = False
 quitting = False
-interruptable = False
+interruptible = False
 
 def main(del_exitfunc=False):
 """Start the Python execution server in a subprocess
@@ -575,14 +575,14 @@ def __init__(self, rpchandler):
 self.locals = {}
 
 def runcode(self, code):
-global interruptable
+global interruptible
 try:
 self.user_exc_info = None
-interruptable = True
+interruptible = True
 try:
 exec(code, self.locals)
 finally:
-interruptable = False
+interruptible = False
 except SystemExit as e:
 if e.args:  # SystemExit called with an argument.
 ob = e.args[0]
@@ -608,7 +608,7 @@ def runcode(self, code):
 flush_stdout()
 
 def interrupt_the_server(self):
-if interruptable:
+if interruptible:
 thread.interrupt_main()
 
 def start_the_debugger(self, gui_adap_oid):

___
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-124944: Add socket.SO_ORIGINAL_DST (#124945)

2024-10-14 Thread erlend-aasland
https://github.com/python/cpython/commit/1bffd7a2a738506a4ad50c6c3c2c32926cce6d14
commit: 1bffd7a2a738506a4ad50c6c3c2c32926cce6d14
branch: main
author: Steven Jin 
committer: erlend-aasland 
date: 2024-10-15T00:36:38+02:00
summary:

gh-124944: Add socket.SO_ORIGINAL_DST (#124945)

files:
A Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst
M Modules/socketmodule.c
M Modules/socketmodule.h
M configure
M configure.ac
M pyconfig.h.in

diff --git 
a/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst 
b/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst
new file mode 100644
index 00..66af712c5ae5a8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-03-17-13-22.gh-issue-124944.YyLAzf.rst
@@ -0,0 +1 @@
+Add ``SO_ORIGINAL_DST`` to the :mod:`socket` module.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 0829d2358129d2..744e5e0c0b2b54 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -7921,6 +7921,9 @@ socket_exec(PyObject *m)
 #ifdef  SO_OOBINLINE
 ADD_INT_MACRO(m, SO_OOBINLINE);
 #endif
+#ifdef  SO_ORIGINAL_DST
+ADD_INT_MACRO(m, SO_ORIGINAL_DST);
+#endif
 #ifndef __GNU__
 #ifdef  SO_REUSEPORT
 ADD_INT_MACRO(m, SO_REUSEPORT);
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index a77c620c2ef630..e1d96377728eb9 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -172,6 +172,10 @@ typedef int socklen_t;
 # undef AF_VSOCK
 #endif
 
+#ifdef HAVE_LINUX_NETFILTER_IPV4_H
+# include 
+#endif
+
 #ifdef HAVE_SOCKADDR_ALG
 
 # include 
diff --git a/configure b/configure
index 0cc73e4e66552d..c5bec6a1b0d7c2 100755
--- a/configure
+++ b/configure
@@ -11092,6 +11092,12 @@ if test "x$ac_cv_header_linux_memfd_h" = xyes
 then :
   printf "%s\n" "#define HAVE_LINUX_MEMFD_H 1" >>confdefs.h
 
+fi
+ac_fn_c_check_header_compile "$LINENO" "linux/netfilter_ipv4.h" 
"ac_cv_header_linux_netfilter_ipv4_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_netfilter_ipv4_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LINUX_NETFILTER_IPV4_H 1" >>confdefs.h
+
 fi
 ac_fn_c_check_header_compile "$LINENO" "linux/random.h" 
"ac_cv_header_linux_random_h" "$ac_includes_default"
 if test "x$ac_cv_header_linux_random_h" = xyes
diff --git a/configure.ac b/configure.ac
index 1864e94ace9243..d4b7942190207a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3013,7 +3013,7 @@ AC_DEFINE([STDC_HEADERS], [1],
 AC_CHECK_HEADERS([ \
   alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h 
fcntl.h grp.h \
   io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h 
linux/limits.h linux/memfd.h \
-  linux/random.h linux/soundcard.h \
+  linux/netfilter_ipv4.h linux/random.h linux/soundcard.h \
   linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h 
netpacket/packet.h poll.h process.h pthread.h pty.h \
   sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h 
sys/bsdtty.h sys/devpoll.h \
   sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h 
sys/kern_control.h \
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 7f02603e26f5d0..1947d8ee14f83e 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -739,6 +739,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_LINUX_MEMFD_H
 
+/* Define to 1 if you have the  header file. */
+#undef HAVE_LINUX_NETFILTER_IPV4_H
+
 /* Define to 1 if you have the  header file. */
 #undef HAVE_LINUX_NETLINK_H
 

___
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-124958: Revert "gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles ... (#125486)

2024-10-14 Thread 1st1
https://github.com/python/cpython/commit/0b28ea4a35dc7c68c97127f7aad8f0175d77c520
commit: 0b28ea4a35dc7c68c97127f7aad8f0175d77c520
branch: main
author: Thomas Grainger 
committer: 1st1 
date: 2024-10-14T15:45:58-07:00
summary:

gh-124958: Revert "gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and 
_PyFuture refcycles ... (#125486)

* Revert "gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture 
refcycles (#12… (#125476)"

This reverts commit e99650b80ace3893c2a80b3f2a4aca99cb305191.

* fix incompatability with gh-124392

files:
A Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst
M Lib/asyncio/futures.py
M Lib/asyncio/taskgroups.py
M Lib/test/test_asyncio/test_futures.py
M Lib/test/test_asyncio/test_taskgroups.py

diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 5f6fa2348726cf..c95fce035cd548 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -190,8 +190,7 @@ def result(self):
 the future is done and has an exception set, this exception is raised.
 """
 if self._state == _CANCELLED:
-exc = self._make_cancelled_error()
-raise exc
+raise self._make_cancelled_error()
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Result is not ready.')
 self.__log_traceback = False
@@ -208,8 +207,7 @@ def exception(self):
 InvalidStateError.
 """
 if self._state == _CANCELLED:
-exc = self._make_cancelled_error()
-raise exc
+raise self._make_cancelled_error()
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Exception is not set.')
 self.__log_traceback = False
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index f2ee9648c43876..9fa772ca9d02cc 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -66,6 +66,20 @@ async def __aenter__(self):
 return self
 
 async def __aexit__(self, et, exc, tb):
+tb = None
+try:
+return await self._aexit(et, exc)
+finally:
+# Exceptions are heavy objects that can have object
+# cycles (bad for GC); let's not keep a reference to
+# a bunch of them. It would be nicer to use a try/finally
+# in __aexit__ directly but that introduced some diff noise
+self._parent_task = None
+self._errors = None
+self._base_error = None
+exc = None
+
+async def _aexit(self, et, exc):
 self._exiting = True
 
 if (exc is not None and
@@ -122,7 +136,10 @@ async def __aexit__(self, et, exc, tb):
 assert not self._tasks
 
 if self._base_error is not None:
-raise self._base_error
+try:
+raise self._base_error
+finally:
+exc = None
 
 if self._parent_cancel_requested:
 # If this flag is set we *must* call uncancel().
@@ -133,8 +150,14 @@ async def __aexit__(self, et, exc, tb):
 
 # Propagate CancelledError if there is one, except if there
 # are other errors -- those have priority.
-if propagate_cancellation_error is not None and not self._errors:
-raise propagate_cancellation_error
+try:
+if propagate_cancellation_error is not None and not self._errors:
+try:
+raise propagate_cancellation_error
+finally:
+exc = None
+finally:
+propagate_cancellation_error = None
 
 if et is not None and not issubclass(et, exceptions.CancelledError):
 self._errors.append(exc)
@@ -146,14 +169,14 @@ async def __aexit__(self, et, exc, tb):
 if self._parent_task.cancelling():
 self._parent_task.uncancel()
 self._parent_task.cancel()
-# Exceptions are heavy objects that can have object
-# cycles (bad for GC); let's not keep a reference to
-# a bunch of them.
 try:
-me = BaseExceptionGroup('unhandled errors in a TaskGroup', 
self._errors)
-raise me from None
+raise BaseExceptionGroup(
+'unhandled errors in a TaskGroup',
+self._errors,
+) from None
 finally:
-self._errors = None
+exc = None
+
 
 def create_task(self, coro, *, name=None, context=None):
 """Create a new task in this group and return it.
diff --git a/Lib/test/test_asyncio/test_futures.py 
b/Lib/test/test_asyncio/test_futures.py
index 458b70451a306a..c566b28adb2408 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -659,6 +659,28 @@ def __del__(self):
 fut = self._new_future(loop=self.loop)
 fut.set_result(Evil())
 
+

[Python-checkins] [3.13] Fix idlelib typos (GH-125484) (#125487)

2024-10-14 Thread terryjreedy
https://github.com/python/cpython/commit/6fb48c69fc6d73567177db1b65ba11a52c62a143
commit: 6fb48c69fc6d73567177db1b65ba11a52c62a143
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: terryjreedy 
date: 2024-10-14T21:38:40Z
summary:

[3.13] Fix idlelib typos (GH-125484) (#125487)

Fix idlelib typos (GH-125484)

Propagate fixes in Doc/library/idle.rst to help.html.
Change 'interruptable' to 'interruptible' in run.py.
The latter was reported by ember91 in PR 125473.
(cherry picked from commit 3fea1d000ef0a74062fd3fe218ad94618b08d9f2)

Co-authored-by: Terry Jan Reedy 

files:
M Lib/idlelib/help.html
M Lib/idlelib/run.py

diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html
index 827d230b54e159..2a4adc6a4d395f 100644
--- a/Lib/idlelib/help.html
+++ b/Lib/idlelib/help.html
@@ -5,7 +5,7 @@
 
 
 
-IDLE — Python 3.13.0a2 documentation
+IDLE — Python 3.14.0a0 documentation
 
 
 
@@ -18,7 +18,7 @@
 
 
 
 
 
@@ -26,6 +26,7 @@
 
 
 
+
 https://docs.python.org/3/library/idle.html"; />
 
 
@@ -45,6 +46,8 @@
 
 
 
+
+
 
   
 
@@ -184,7 +187,7 @@ Navigation
 
   
 
-  3.13.0a2 Documentation »
+  3.14.0a0 Documentation »
 
 
   The Python 
Standard Library »
@@ -554,7 +557,7 @@ Key bindingsControl 
key on Windows and
-Unix and the Command key 
on macOS.  (And all such dicussions
+Unix and the Command key 
on macOS.  (And all such discussions
 assume that the keys have not been re-bound to something else.)
 
 Arrow keys move the cursor one character or line.
@@ -562,8 +565,8 @@ Key bindingsHome and End go to the beginning or end 
of the line.
 Page Up and Page Down go up or down one 
screen.
 C-Home and C-End go to beginning or end 
of the file.
-Backspace and Del (or C-d) delete 
the previous or
-next character.
+Backspace and Del (or C-d) delete the previous
+or next character.
 C-Backspace and C-Del delete one word left 
or right.
 C-k deletes (‘kills’) everything to the right.
 
@@ -694,7 +697,7 @@ Shell window
-C-c attemps to interrupt statement execution (but may 
fail).
+C-c attempts to interrupt statement execution (but may 
fail).
 C-d closes Shell if typed at a >>> 
prompt.
 Alt-p and Alt-n (C-p and C-n on macOS)
 retrieve to the current prompt the previous or next previously
@@ -1136,7 +1139,7 @@ Navigation
 
   
 
-  3.13.0a2 Documentation »
+  3.14.0a0 Documentation »
 
 
   The Python 
Standard Library »
@@ -1180,7 +1183,7 @@ Navigation
 
 
 
-Last updated on Jan 17, 2024 (06:57 UTC).
+Last updated on Oct 14, 2024 (20:27 UTC).
 Found a bug?
 
 
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index 8f98e73258e778..a30db99a619a93 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -108,11 +108,11 @@ def handle_tk_events(tcl=tcl):
 
 # Thread shared globals: Establish a queue between a subthread (which handles
 # the socket) and the main thread (which runs user code), plus global
-# completion, exit and interruptable (the main thread) flags:
+# completion, exit and interruptible (the main thread) flags:
 
 exit_now = False
 quitting = False
-interruptable = False
+interruptible = False
 
 def main(del_exitfunc=False):
 """Start the Python execution server in a subprocess
@@ -582,14 +582,14 @@ def __init__(self, rpchandler):
 self.locals = {}
 
 def runcode(self, code):
-global interruptable
+global interruptible
 try:
 self.user_exc_info = None
-interruptable = True
+interruptible = True
 try:
 exec(code, self.locals)
 finally:
-interruptable = False
+interruptible = False
 except SystemExit as e:
 if e.args:  # SystemExit called with an argument.
 ob = e.args[0]
@@ -615,7 +615,7 @@ def runcode(self, code):
 flush_stdout()
 
 def interrupt_the_server(self):
-if interruptable:
+if interruptible:
 thread.interrupt_main()
 
 def start_the_debugger(self, gui_adap_oid):

___
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-124872: Replace enter/exit events with "switched" (#124776)

2024-10-14 Thread 1st1
https://github.com/python/cpython/commit/843d28f59d2616d052d9d45f31823976da07f0f3
commit: 843d28f59d2616d052d9d45f31823976da07f0f3
branch: main
author: Richard Hansen 
committer: 1st1 
date: 2024-10-14T12:28:41-07:00
summary:

gh-124872: Replace enter/exit events with "switched" (#124776)

Users want to know when the current context switches to a different
context object.  Right now this happens when and only when a context
is entered or exited, so the enter and exit events are synonymous with
"switched".  However, if the changes proposed for gh-99633 are
implemented, the current context will also switch for reasons other
than context enter or exit.  Since users actually care about context
switches and not enter or exit, replace the enter and exit events with
a single switched event.

The former exit event was emitted just before exiting the context.
The new switched event is emitted after the context is exited to match
the semantics users expect of an event with a past-tense name.  If
users need the ability to clean up before the switch takes effect,
another event type can be added in the future.  It is not added here
because YAGNI.

I skipped 0 in the enum as a matter of practice.  Skipping 0 makes it
easier to troubleshoot when code forgets to set zeroed memory, and it
aligns with best practices for other tools (e.g.,
https://protobuf.dev/programming-guides/dos-donts/#unspecified-enum).

files:
M Doc/c-api/contextvars.rst
M Include/cpython/context.h
M Lib/test/test_capi/test_watchers.py
M Modules/_testcapi/watchers.c
M Python/context.c
M Tools/c-analyzer/cpython/ignored.tsv

diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst
index 8eba54a80dc80d..b7c6550ff34aac 100644
--- a/Doc/c-api/contextvars.rst
+++ b/Doc/c-api/contextvars.rst
@@ -123,16 +123,10 @@ Context object management functions:
 
Enumeration of possible context object watcher events:
 
-   - ``Py_CONTEXT_EVENT_ENTER``: A context has been entered, causing the
- :term:`current context` to switch to it.  The object passed to the watch
- callback is the now-current :class:`contextvars.Context` object.  Each
- enter event will eventually have a corresponding exit event for the same
- context object after any subsequently entered contexts have themselves 
been
- exited.
-   - ``Py_CONTEXT_EVENT_EXIT``: A context is about to be exited, which will
- cause the :term:`current context` to switch back to what it was before the
- context was entered.  The object passed to the watch callback is the
- still-current :class:`contextvars.Context` object.
+   - ``Py_CONTEXT_SWITCHED``: The :term:`current context` has switched to a
+ different context.  The object passed to the watch callback is the
+ now-current :class:`contextvars.Context` object, or None if no context is
+ current.
 
.. versionadded:: 3.14
 
diff --git a/Include/cpython/context.h b/Include/cpython/context.h
index 3c9be7873b9399..3a7a4b459c09ad 100644
--- a/Include/cpython/context.h
+++ b/Include/cpython/context.h
@@ -29,20 +29,11 @@ PyAPI_FUNC(int) PyContext_Exit(PyObject *);
 
 typedef enum {
 /*
- * A context has been entered, causing the "current context" to switch to
- * it.  The object passed to the watch callback is the now-current
- * contextvars.Context object.  Each enter event will eventually have a
- * corresponding exit event for the same context object after any
- * subsequently entered contexts have themselves been exited.
+ * The current context has switched to a different context.  The object
+ * passed to the watch callback is the now-current contextvars.Context
+ * object, or None if no context is current.
  */
-Py_CONTEXT_EVENT_ENTER,
-/*
- * A context is about to be exited, which will cause the "current context"
- * to switch back to what it was before the context was entered.  The
- * object passed to the watch callback is the still-current
- * contextvars.Context object.
- */
-Py_CONTEXT_EVENT_EXIT,
+Py_CONTEXT_SWITCHED = 1,
 } PyContextEvent;
 
 /*
diff --git a/Lib/test/test_capi/test_watchers.py 
b/Lib/test/test_capi/test_watchers.py
index f21d2627c6094b..4680d6765de122 100644
--- a/Lib/test/test_capi/test_watchers.py
+++ b/Lib/test/test_capi/test_watchers.py
@@ -577,68 +577,62 @@ class TestContextObjectWatchers(unittest.TestCase):
 def context_watcher(self, which_watcher):
 wid = _testcapi.add_context_watcher(which_watcher)
 try:
-yield wid
+switches = _testcapi.get_context_switches(which_watcher)
+except ValueError:
+switches = None
+try:
+yield switches
 finally:
 _testcapi.clear_context_watcher(wid)
 
-def assert_event_counts(self, exp_enter_0, exp_exit_0,
-exp_enter_1, exp_exit_1):
-self.assertEqual(
-exp_enter_0, _testcapi.get_context_watcher_num_enter_events(0))
-

[Python-checkins] Fix idlelib typos (#125484)

2024-10-14 Thread terryjreedy
https://github.com/python/cpython/commit/3fea1d000ef0a74062fd3fe218ad94618b08d9f2
commit: 3fea1d000ef0a74062fd3fe218ad94618b08d9f2
branch: main
author: Terry Jan Reedy 
committer: terryjreedy 
date: 2024-10-14T17:11:58-04:00
summary:

Fix idlelib typos (#125484)

Propagate fixes in Doc/library/idle.rst to help.html.
Change 'interruptable' to 'interruptible' in run.py.
The latter was reported by ember91 in PR 125473.

files:
M Lib/idlelib/help.html
M Lib/idlelib/run.py

diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html
index 827d230b54e159..2a4adc6a4d395f 100644
--- a/Lib/idlelib/help.html
+++ b/Lib/idlelib/help.html
@@ -5,7 +5,7 @@
 
 
 
-IDLE — Python 3.13.0a2 documentation
+IDLE — Python 3.14.0a0 documentation
 
 
 
@@ -18,7 +18,7 @@
 
 
 
 
 
@@ -26,6 +26,7 @@
 
 
 
+
 https://docs.python.org/3/library/idle.html"; />
 
 
@@ -45,6 +46,8 @@
 
 
 
+
+
 
   
 
@@ -184,7 +187,7 @@ Navigation
 
   
 
-  3.13.0a2 Documentation »
+  3.14.0a0 Documentation »
 
 
   The Python 
Standard Library »
@@ -554,7 +557,7 @@ Key bindingsControl 
key on Windows and
-Unix and the Command key 
on macOS.  (And all such dicussions
+Unix and the Command key 
on macOS.  (And all such discussions
 assume that the keys have not been re-bound to something else.)
 
 Arrow keys move the cursor one character or line.
@@ -562,8 +565,8 @@ Key bindingsHome and End go to the beginning or end 
of the line.
 Page Up and Page Down go up or down one 
screen.
 C-Home and C-End go to beginning or end 
of the file.
-Backspace and Del (or C-d) delete 
the previous or
-next character.
+Backspace and Del (or C-d) delete the previous
+or next character.
 C-Backspace and C-Del delete one word left 
or right.
 C-k deletes (‘kills’) everything to the right.
 
@@ -694,7 +697,7 @@ Shell window
-C-c attemps to interrupt statement execution (but may 
fail).
+C-c attempts to interrupt statement execution (but may 
fail).
 C-d closes Shell if typed at a >>> 
prompt.
 Alt-p and Alt-n (C-p and C-n on macOS)
 retrieve to the current prompt the previous or next previously
@@ -1136,7 +1139,7 @@ Navigation
 
   
 
-  3.13.0a2 Documentation »
+  3.14.0a0 Documentation »
 
 
   The Python 
Standard Library »
@@ -1180,7 +1183,7 @@ Navigation
 
 
 
-Last updated on Jan 17, 2024 (06:57 UTC).
+Last updated on Oct 14, 2024 (20:27 UTC).
 Found a bug?
 
 
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index 8f98e73258e778..a30db99a619a93 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -108,11 +108,11 @@ def handle_tk_events(tcl=tcl):
 
 # Thread shared globals: Establish a queue between a subthread (which handles
 # the socket) and the main thread (which runs user code), plus global
-# completion, exit and interruptable (the main thread) flags:
+# completion, exit and interruptible (the main thread) flags:
 
 exit_now = False
 quitting = False
-interruptable = False
+interruptible = False
 
 def main(del_exitfunc=False):
 """Start the Python execution server in a subprocess
@@ -582,14 +582,14 @@ def __init__(self, rpchandler):
 self.locals = {}
 
 def runcode(self, code):
-global interruptable
+global interruptible
 try:
 self.user_exc_info = None
-interruptable = True
+interruptible = True
 try:
 exec(code, self.locals)
 finally:
-interruptable = False
+interruptible = False
 except SystemExit as e:
 if e.args:  # SystemExit called with an argument.
 ob = e.args[0]
@@ -615,7 +615,7 @@ def runcode(self, code):
 flush_stdout()
 
 def interrupt_the_server(self):
-if interruptable:
+if interruptible:
 thread.interrupt_main()
 
 def start_the_debugger(self, gui_adap_oid):

___
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-85453: Improve variable mark up for datetime.rst (#120702)

2024-10-14 Thread erlend-aasland
https://github.com/python/cpython/commit/2a5cdb251674ce8d9a824c102f7cd846d944cfa4
commit: 2a5cdb251674ce8d9a824c102f7cd846d944cfa4
branch: main
author: edson duarte 
committer: erlend-aasland 
date: 2024-10-15T00:02:58+02:00
summary:

gh-85453: Improve variable mark up for datetime.rst (#120702)

Variables and literals are marked up using backticks.

files:
M Doc/library/datetime.rst

diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index f0b465bc9ce39c..2f81080d525f86 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -180,19 +180,19 @@ Objects of the :class:`date` type are always naive.
 
 An object of type :class:`.time` or :class:`.datetime` may be aware or naive.
 
-A :class:`.datetime` object *d* is aware if both of the following hold:
+A :class:`.datetime` object ``d`` is aware if both of the following hold:
 
 1. ``d.tzinfo`` is not ``None``
 2. ``d.tzinfo.utcoffset(d)`` does not return ``None``
 
-Otherwise, *d* is naive.
+Otherwise, ``d`` is naive.
 
-A :class:`.time` object *t* is aware if both of the following hold:
+A :class:`.time` object ``t`` is aware if both of the following hold:
 
 1. ``t.tzinfo`` is not ``None``
 2. ``t.tzinfo.utcoffset(None)`` does not return ``None``.
 
-Otherwise, *t* is naive.
+Otherwise, ``t`` is naive.
 
 The distinction between aware and naive doesn't apply to :class:`timedelta`
 objects.
@@ -358,8 +358,8 @@ Supported operations:
 
++---+
 | ``q, r = divmod(t1, t2)``  | Computes the quotient and the remainder:
  |
 || ``q = t1 // t2`` (3) and ``r = t1 % t2``.   
  |
-|| q is an integer and r is a 
:class:`timedelta` |
-|| object. 
  |
+|| ``q`` is an integer and ``r`` is a  
  |
+|| :class:`timedelta` object.  
  |
 
++---+
 | ``+t1``| Returns a :class:`timedelta` object with 
the  |
 || same value. (2) 
  |
@@ -526,7 +526,7 @@ Other constructors, all class methods:
January 1 of year 1 has ordinal 1.
 
:exc:`ValueError` is raised unless ``1 <= ordinal <=
-   date.max.toordinal()``. For any date *d*,
+   date.max.toordinal()``. For any date ``d``,
``date.fromordinal(d.toordinal()) == d``.
 
 
@@ -730,7 +730,7 @@ Instance methods:
 .. method:: date.toordinal()
 
Return the proleptic Gregorian ordinal of the date, where January 1 of year 
1
-   has ordinal 1. For any :class:`date` object *d*,
+   has ordinal 1. For any :class:`date` object ``d``,
``date.fromordinal(d.toordinal()) == d``.
 
 
@@ -782,7 +782,7 @@ Instance methods:
 
 .. method:: date.__str__()
 
-   For a date *d*, ``str(d)`` is equivalent to ``d.isoformat()``.
+   For a date ``d``, ``str(d)`` is equivalent to ``d.isoformat()``.
 
 
 .. method:: date.ctime()
@@ -1063,7 +1063,7 @@ Other constructors, all class methods:
is used.  If the *date* argument is a :class:`.datetime` object, its time 
components
and :attr:`.tzinfo` attributes are ignored.
 
-   For any :class:`.datetime` object *d*,
+   For any :class:`.datetime` object ``d``,
``d == datetime.combine(d.date(), d.time(), d.tzinfo)``.
 
.. versionchanged:: 3.6
@@ -1270,11 +1270,11 @@ Supported operations:
 
If both are naive, or both are aware and have the same 
:attr:`~.datetime.tzinfo` attribute,
the :attr:`~.datetime.tzinfo` attributes are ignored, and the result is a 
:class:`timedelta`
-   object *t* such that ``datetime2 + t == datetime1``. No time zone 
adjustments
+   object ``t`` such that ``datetime2 + t == datetime1``. No time zone 
adjustments
are done in this case.
 
If both are aware and have different :attr:`~.datetime.tzinfo` attributes, 
``a-b`` acts
-   as if *a* and *b* were first converted to naive UTC datetimes. The
+   as if ``a`` and ``b`` were first converted to naive UTC datetimes. The
result is ``(a.replace(tzinfo=None) - a.utcoffset()) - 
(b.replace(tzinfo=None)
- b.utcoffset())`` except that the implementation never overflows.
 
@@ -1454,11 +1454,11 @@ Instance methods:
 
 .. method:: datetime.utctimetuple()
 
-   If :class:`.datetime` instance *d* is naive, this is the same as
+   If :class:`.datetime` instance ``d`` is naive, this is the same as
``d.timetuple()`` except that :attr:`~.time.struct_time.tm_isdst` is forced 
to 0 regardless of what
``d.dst()`` returns. DST is never in effect for a UTC time.
 
-   If *d* is aware, *d* is normalized to UTC time, by subtracting
+   If ``d`` is aware, ``d`` is normalized to UTC time, by subtracting
``d.utcoffset()``, and a :class:`time.struct_time` for the
normalized time is returned. :attr:`!tm_isdst` is for

[Python-checkins] [3.13] gh-85453: Improve variable mark up for datetime.rst (GH-120702) (#125490)

2024-10-14 Thread erlend-aasland
https://github.com/python/cpython/commit/624a8e4f976bf64851d51ff7ff7d7e24ad87c142
commit: 624a8e4f976bf64851d51ff7ff7d7e24ad87c142
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: erlend-aasland 
date: 2024-10-14T22:08:30Z
summary:

[3.13] gh-85453: Improve variable mark up for datetime.rst (GH-120702) (#125490)

Variables and literals are marked up using backticks.
(cherry picked from commit 2a5cdb251674ce8d9a824c102f7cd846d944cfa4)

Co-authored-by: edson duarte 

files:
M Doc/library/datetime.rst

diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index 4775aa628e9385..211e625c4303b0 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -180,19 +180,19 @@ Objects of the :class:`date` type are always naive.
 
 An object of type :class:`.time` or :class:`.datetime` may be aware or naive.
 
-A :class:`.datetime` object *d* is aware if both of the following hold:
+A :class:`.datetime` object ``d`` is aware if both of the following hold:
 
 1. ``d.tzinfo`` is not ``None``
 2. ``d.tzinfo.utcoffset(d)`` does not return ``None``
 
-Otherwise, *d* is naive.
+Otherwise, ``d`` is naive.
 
-A :class:`.time` object *t* is aware if both of the following hold:
+A :class:`.time` object ``t`` is aware if both of the following hold:
 
 1. ``t.tzinfo`` is not ``None``
 2. ``t.tzinfo.utcoffset(None)`` does not return ``None``.
 
-Otherwise, *t* is naive.
+Otherwise, ``t`` is naive.
 
 The distinction between aware and naive doesn't apply to :class:`timedelta`
 objects.
@@ -358,8 +358,8 @@ Supported operations:
 
++---+
 | ``q, r = divmod(t1, t2)``  | Computes the quotient and the remainder:
  |
 || ``q = t1 // t2`` (3) and ``r = t1 % t2``.   
  |
-|| q is an integer and r is a 
:class:`timedelta` |
-|| object. 
  |
+|| ``q`` is an integer and ``r`` is a  
  |
+|| :class:`timedelta` object.  
  |
 
++---+
 | ``+t1``| Returns a :class:`timedelta` object with 
the  |
 || same value. (2) 
  |
@@ -526,7 +526,7 @@ Other constructors, all class methods:
January 1 of year 1 has ordinal 1.
 
:exc:`ValueError` is raised unless ``1 <= ordinal <=
-   date.max.toordinal()``. For any date *d*,
+   date.max.toordinal()``. For any date ``d``,
``date.fromordinal(d.toordinal()) == d``.
 
 
@@ -697,7 +697,7 @@ Instance methods:
 .. method:: date.toordinal()
 
Return the proleptic Gregorian ordinal of the date, where January 1 of year 
1
-   has ordinal 1. For any :class:`date` object *d*,
+   has ordinal 1. For any :class:`date` object ``d``,
``date.fromordinal(d.toordinal()) == d``.
 
 
@@ -749,7 +749,7 @@ Instance methods:
 
 .. method:: date.__str__()
 
-   For a date *d*, ``str(d)`` is equivalent to ``d.isoformat()``.
+   For a date ``d``, ``str(d)`` is equivalent to ``d.isoformat()``.
 
 
 .. method:: date.ctime()
@@ -1030,7 +1030,7 @@ Other constructors, all class methods:
is used.  If the *date* argument is a :class:`.datetime` object, its time 
components
and :attr:`.tzinfo` attributes are ignored.
 
-   For any :class:`.datetime` object *d*,
+   For any :class:`.datetime` object ``d``,
``d == datetime.combine(d.date(), d.time(), d.tzinfo)``.
 
.. versionchanged:: 3.6
@@ -1237,11 +1237,11 @@ Supported operations:
 
If both are naive, or both are aware and have the same 
:attr:`~.datetime.tzinfo` attribute,
the :attr:`~.datetime.tzinfo` attributes are ignored, and the result is a 
:class:`timedelta`
-   object *t* such that ``datetime2 + t == datetime1``. No time zone 
adjustments
+   object ``t`` such that ``datetime2 + t == datetime1``. No time zone 
adjustments
are done in this case.
 
If both are aware and have different :attr:`~.datetime.tzinfo` attributes, 
``a-b`` acts
-   as if *a* and *b* were first converted to naive UTC datetimes. The
+   as if ``a`` and ``b`` were first converted to naive UTC datetimes. The
result is ``(a.replace(tzinfo=None) - a.utcoffset()) - 
(b.replace(tzinfo=None)
- b.utcoffset())`` except that the implementation never overflows.
 
@@ -1421,11 +1421,11 @@ Instance methods:
 
 .. method:: datetime.utctimetuple()
 
-   If :class:`.datetime` instance *d* is naive, this is the same as
+   If :class:`.datetime` instance ``d`` is naive, this is the same as
``d.timetuple()`` except that :attr:`~.time.struct_time.tm_isdst` is forced 
to 0 regardless of what
``d.dst()`` returns. DST is never in effect for a UTC time.
 
-   If *d* is aware, *d* is normalized to UTC time, by subtracting
+   If ``d`` is awa

[Python-checkins] [3.12] gh-85453: Improve variable mark up for datetime.rst (GH-120702) (#125491)

2024-10-14 Thread erlend-aasland
https://github.com/python/cpython/commit/449f2c98bdd04694a987639a91f4fab366c2e9d4
commit: 449f2c98bdd04694a987639a91f4fab366c2e9d4
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: erlend-aasland 
date: 2024-10-14T22:09:23Z
summary:

[3.12] gh-85453: Improve variable mark up for datetime.rst (GH-120702) (#125491)

Variables and literals are marked up using backticks.
(cherry picked from commit 2a5cdb251674ce8d9a824c102f7cd846d944cfa4)

Co-authored-by: edson duarte 

files:
M Doc/library/datetime.rst

diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index 671554f2cf3d0d..54ab05e4e66549 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -180,19 +180,19 @@ Objects of the :class:`date` type are always naive.
 
 An object of type :class:`.time` or :class:`.datetime` may be aware or naive.
 
-A :class:`.datetime` object *d* is aware if both of the following hold:
+A :class:`.datetime` object ``d`` is aware if both of the following hold:
 
 1. ``d.tzinfo`` is not ``None``
 2. ``d.tzinfo.utcoffset(d)`` does not return ``None``
 
-Otherwise, *d* is naive.
+Otherwise, ``d`` is naive.
 
-A :class:`.time` object *t* is aware if both of the following hold:
+A :class:`.time` object ``t`` is aware if both of the following hold:
 
 1. ``t.tzinfo`` is not ``None``
 2. ``t.tzinfo.utcoffset(None)`` does not return ``None``.
 
-Otherwise, *t* is naive.
+Otherwise, ``t`` is naive.
 
 The distinction between aware and naive doesn't apply to :class:`timedelta`
 objects.
@@ -358,8 +358,8 @@ Supported operations:
 
++---+
 | ``q, r = divmod(t1, t2)``  | Computes the quotient and the remainder:
  |
 || ``q = t1 // t2`` (3) and ``r = t1 % t2``.   
  |
-|| q is an integer and r is a 
:class:`timedelta` |
-|| object. 
  |
+|| ``q`` is an integer and ``r`` is a  
  |
+|| :class:`timedelta` object.  
  |
 
++---+
 | ``+t1``| Returns a :class:`timedelta` object with 
the  |
 || same value. (2) 
  |
@@ -526,7 +526,7 @@ Other constructors, all class methods:
January 1 of year 1 has ordinal 1.
 
:exc:`ValueError` is raised unless ``1 <= ordinal <=
-   date.max.toordinal()``. For any date *d*,
+   date.max.toordinal()``. For any date ``d``,
``date.fromordinal(d.toordinal()) == d``.
 
 
@@ -678,7 +678,7 @@ Instance methods:
 .. method:: date.toordinal()
 
Return the proleptic Gregorian ordinal of the date, where January 1 of year 
1
-   has ordinal 1. For any :class:`date` object *d*,
+   has ordinal 1. For any :class:`date` object ``d``,
``date.fromordinal(d.toordinal()) == d``.
 
 
@@ -730,7 +730,7 @@ Instance methods:
 
 .. method:: date.__str__()
 
-   For a date *d*, ``str(d)`` is equivalent to ``d.isoformat()``.
+   For a date ``d``, ``str(d)`` is equivalent to ``d.isoformat()``.
 
 
 .. method:: date.ctime()
@@ -1011,7 +1011,7 @@ Other constructors, all class methods:
is used.  If the *date* argument is a :class:`.datetime` object, its time 
components
and :attr:`.tzinfo` attributes are ignored.
 
-   For any :class:`.datetime` object *d*,
+   For any :class:`.datetime` object ``d``,
``d == datetime.combine(d.date(), d.time(), d.tzinfo)``.
 
.. versionchanged:: 3.6
@@ -1200,11 +1200,11 @@ Supported operations:
 
If both are naive, or both are aware and have the same 
:attr:`~.datetime.tzinfo` attribute,
the :attr:`~.datetime.tzinfo` attributes are ignored, and the result is a 
:class:`timedelta`
-   object *t* such that ``datetime2 + t == datetime1``. No time zone 
adjustments
+   object ``t`` such that ``datetime2 + t == datetime1``. No time zone 
adjustments
are done in this case.
 
If both are aware and have different :attr:`~.datetime.tzinfo` attributes, 
``a-b`` acts
-   as if *a* and *b* were first converted to naive UTC datetimes. The
+   as if ``a`` and ``b`` were first converted to naive UTC datetimes. The
result is ``(a.replace(tzinfo=None) - a.utcoffset()) - 
(b.replace(tzinfo=None)
- b.utcoffset())`` except that the implementation never overflows.
 
@@ -1377,11 +1377,11 @@ Instance methods:
 
 .. method:: datetime.utctimetuple()
 
-   If :class:`.datetime` instance *d* is naive, this is the same as
+   If :class:`.datetime` instance ``d`` is naive, this is the same as
``d.timetuple()`` except that :attr:`~.time.struct_time.tm_isdst` is forced 
to 0 regardless of what
``d.dst()`` returns. DST is never in effect for a UTC time.
 
-   If *d* is aware, *d* is normalized to UTC time, by subtracting
+   If ``d`` is awa

[Python-checkins] gh-125269: Use `AC_LINK_IF_ELSE` to detect if `-latomic` is needed (#125416)

2024-10-14 Thread colesbury
https://github.com/python/cpython/commit/8d42e2d915c3096e7eac1c649751d1da567bb7c3
commit: 8d42e2d915c3096e7eac1c649751d1da567bb7c3
branch: main
author: Sam Gross 
committer: colesbury 
date: 2024-10-14T20:09:48-04:00
summary:

gh-125269: Use `AC_LINK_IF_ELSE` to detect if `-latomic` is needed (#125416)

We previously used `AC_RUN_IF_ELSE` with a short test program to detect
if `-latomic` is needed, but that requires choosing a specific default
value when cross-compiling because the test program is not run.
Some cross compilation targets like `wasm32-emscripten` do not support
`-latomic`, while other cross compilation targets, like
`arm-linux-gnueabi` require it.

files:
A Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst
M configure
M configure.ac

diff --git 
a/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst 
b/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst
new file mode 100644
index 00..24f5469e8a664b
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2024-10-13-21-11-30.gh-issue-125269.BC-fdo.rst
@@ -0,0 +1,2 @@
+Fix detection of whether ``-latomic`` is needed when cross-compiling CPython
+using the configure script.
diff --git a/configure b/configure
index c5bec6a1b0d7c2..be119f108a060b 100755
--- a/configure
+++ b/configure
@@ -28999,10 +28999,6 @@ printf %s "checking whether libatomic is needed by 
... " >&6; }
 if test ${ac_cv_libatomic_needed+y}
 then :
   printf %s "(cached) " >&6
-else $as_nop
-  if test "$cross_compiling" = yes
-then :
-ac_cv_libatomic_needed=no
 else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -29044,16 +29040,14 @@ int main()
 }
 
 _ACEOF
-if ac_fn_c_try_run "$LINENO"
+if ac_fn_c_try_link "$LINENO"
 then :
   ac_cv_libatomic_needed=no
 else $as_nop
 ac_cv_libatomic_needed=yes
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+conftest$ac_exeext conftest.$ac_ext
 fi
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libatomic_needed" 
>&5
 printf "%s\n" "$ac_cv_libatomic_needed" >&6; }
diff --git a/configure.ac b/configure.ac
index d4b7942190207a..582851695e400f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7497,7 +7497,7 @@ CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include 
${CPPFLAGS}"
 
 AC_CACHE_CHECK([whether libatomic is needed by ],
[ac_cv_libatomic_needed],
-[AC_RUN_IFELSE([AC_LANG_SOURCE([[
+[AC_LINK_IFELSE([AC_LANG_SOURCE([[
 // pyatomic.h needs uint64_t and Py_ssize_t types
 #include   // int64_t, intptr_t
 #ifdef HAVE_SYS_TYPES_H
@@ -7534,9 +7534,8 @@ int main()
 return 0; // all good
 }
 ]])],
-  [ac_cv_libatomic_needed=no],  dnl build succeeded
-  [ac_cv_libatomic_needed=yes], dnl build failed
-  [ac_cv_libatomic_needed=no])  dnl cross compilation
+  [ac_cv_libatomic_needed=no],  dnl build and link succeeded
+  [ac_cv_libatomic_needed=yes]) dnl build and link failed
 ])
 
 AS_VAR_IF([ac_cv_libatomic_needed], [yes],

___
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-125323: Remove some unsafe Py_DECREFs in bytecodes.c, replacing them with PyStackRef_CLOSEs (GH-125324)

2024-10-14 Thread markshannon
https://github.com/python/cpython/commit/4b358ee647809019813f106eb901f466a3846d98
commit: 4b358ee647809019813f106eb901f466a3846d98
branch: main
author: Ken Jin 
committer: markshannon 
date: 2024-10-14T09:17:51+01:00
summary:

gh-125323: Remove some unsafe Py_DECREFs in bytecodes.c, replacing them with 
PyStackRef_CLOSEs (GH-125324)

files:
M Include/internal/pycore_stackref.h
M Python/bytecodes.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Tools/cases_generator/analyzer.py
M Tools/cases_generator/generators_common.py

diff --git a/Include/internal/pycore_stackref.h 
b/Include/internal/pycore_stackref.h
index 7d1eb11aa5ecb8..0e6410466b924b 100644
--- a/Include/internal/pycore_stackref.h
+++ b/Include/internal/pycore_stackref.h
@@ -153,6 +153,8 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
 return PyStackRef_FromPyObjectSteal(PyStackRef_AsPyObjectSteal(stackref));
 }
 
+#define PyStackRef_CLOSE_SPECIALIZED(stackref, dealloc) 
PyStackRef_CLOSE(stackref)
+
 
 #else // Py_GIL_DISABLED
 
@@ -177,6 +179,7 @@ static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
 
 #define PyStackRef_DUP(stackref) 
PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)))
 
+#define PyStackRef_CLOSE_SPECIALIZED(stackref, dealloc) 
_Py_DECREF_SPECIALIZED(PyStackRef_AsPyObjectBorrow(stackref), dealloc)
 
 #endif // Py_GIL_DISABLED
 
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 34fdfcb05e3c18..299608f252c546 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -474,8 +474,8 @@ dummy_func(
 
 STAT_INC(BINARY_OP, hit);
 PyObject *res_o = _PyLong_Multiply((PyLongObject *)left_o, 
(PyLongObject *)right_o);
-_Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free);
-_Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free);
+PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free);
+PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free);
 INPUTS_DEAD();
 ERROR_IF(res_o == NULL, error);
 res = PyStackRef_FromPyObjectSteal(res_o);
@@ -487,8 +487,8 @@ dummy_func(
 
 STAT_INC(BINARY_OP, hit);
 PyObject *res_o = _PyLong_Add((PyLongObject *)left_o, 
(PyLongObject *)right_o);
-_Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free);
-_Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free);
+PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free);
+PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free);
 INPUTS_DEAD();
 ERROR_IF(res_o == NULL, error);
 res = PyStackRef_FromPyObjectSteal(res_o);
@@ -500,8 +500,8 @@ dummy_func(
 
 STAT_INC(BINARY_OP, hit);
 PyObject *res_o = _PyLong_Subtract((PyLongObject *)left_o, 
(PyLongObject *)right_o);
-_Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free);
-_Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free);
+PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free);
+PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free);
 INPUTS_DEAD();
 ERROR_IF(res_o == NULL, error);
 res = PyStackRef_FromPyObjectSteal(res_o);
@@ -594,8 +594,8 @@ dummy_func(
 
 STAT_INC(BINARY_OP, hit);
 PyObject *res_o = PyUnicode_Concat(left_o, right_o);
-_Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc);
-_Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc);
+PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
+PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
 INPUTS_DEAD();
 ERROR_IF(res_o == NULL, error);
 res = PyStackRef_FromPyObjectSteal(res_o);
@@ -636,12 +636,12 @@ dummy_func(
  * that the string is safe to mutate.
  */
 assert(Py_REFCNT(left_o) >= 2);
-_Py_DECREF_NO_DEALLOC(left_o);
+PyStackRef_CLOSE(left);
 DEAD(left);
 PyObject *temp = PyStackRef_AsPyObjectBorrow(*target_local);
 PyUnicode_Append(&temp, right_o);
 *target_local = PyStackRef_FromPyObjectSteal(temp);
-_Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc);
+PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
 DEAD(right);
 ERROR_IF(PyStackRef_IsNull(*target_local), error);
 #if TIER_ONE
@@ -755,7 +755,7 @@ dummy_func(
 PyObject *res_o = PyList_GET_ITEM(list, index);
 assert(res_o != NULL);
 Py_INCREF(res_o);
-_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
+PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
 DEAD(sub_st);
 PyStackRef_CLOSE(list_st);
 res = PyStackRef_FromPyObjectSteal(re

[Python-checkins] gh-121797: Add class method Fraction.from_number() (GH-121800)

2024-10-14 Thread serhiy-storchaka
https://github.com/python/cpython/commit/b52c7306ea4470f9d7548655c2a1b89a07ff5504
commit: b52c7306ea4470f9d7548655c2a1b89a07ff5504
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2024-10-14T07:54:59Z
summary:

gh-121797: Add class method Fraction.from_number() (GH-121800)

It is an alternative constructor which only accepts a single numeric argument.
Unlike to Fraction.from_float() and Fraction.from_decimal() it accepts any
real numbers supported by the standard constructor (int, float, Decimal,
Rational numbers, objects with as_integer_ratio()).
Unlike to the standard constructor, it does not accept strings.

files:
A Misc/NEWS.d/next/Library/2024-07-15-19-34-56.gh-issue-121797.qDqj59.rst
M Doc/library/fractions.rst
M Doc/whatsnew/3.14.rst
M Lib/fractions.py
M Lib/test/test_fractions.py

diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst
index 2ee154952549ac..fc7f9a6301a915 100644
--- a/Doc/library/fractions.rst
+++ b/Doc/library/fractions.rst
@@ -166,6 +166,16 @@ another rational number, or from a string.
  instance.
 
 
+   .. classmethod:: from_number(number)
+
+  Alternative constructor which only accepts instances of
+  :class:`numbers.Integral`, :class:`numbers.Rational`,
+  :class:`float` or :class:`decimal.Decimal`, and objects with
+  the :meth:`!as_integer_ratio` method, but not strings.
+
+  .. versionadded:: 3.14
+
+
.. method:: limit_denominator(max_denominator=100)
 
   Finds and returns the closest :class:`Fraction` to ``self`` that has
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index c62a3ca5872eef..b22d1bd1e99d4e 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -263,6 +263,10 @@ fractions
   :meth:`!as_integer_ratio` method to a :class:`~fractions.Fraction`.
   (Contributed by Serhiy Storchaka in :gh:`82017`.)
 
+* Add alternative :class:`~fractions.Fraction` constructor
+  :meth:`Fraction.from_number() `.
+  (Contributed by Serhiy Storchaka in :gh:`121797`.)
+
 
 functools
 -
diff --git a/Lib/fractions.py b/Lib/fractions.py
index 34fd0803d1b1ab..f0cbc8c2e6c012 100644
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -279,7 +279,8 @@ def __new__(cls, numerator=0, denominator=None):
 numerator = -numerator
 
 else:
-raise TypeError("argument should be a string or a number")
+raise TypeError("argument should be a string or a Rational "
+"instance or have the as_integer_ratio() 
method")
 
 elif type(numerator) is int is type(denominator):
 pass # *very* normal case
@@ -305,6 +306,28 @@ def __new__(cls, numerator=0, denominator=None):
 self._denominator = denominator
 return self
 
+@classmethod
+def from_number(cls, number):
+"""Converts a finite real number to a rational number, exactly.
+
+Beware that Fraction.from_number(0.3) != Fraction(3, 10).
+
+"""
+if type(number) is int:
+return cls._from_coprime_ints(number, 1)
+
+elif isinstance(number, numbers.Rational):
+return cls._from_coprime_ints(number.numerator, number.denominator)
+
+elif (isinstance(number, float) or
+  (not isinstance(number, type) and
+   hasattr(number, 'as_integer_ratio'))):
+return cls._from_coprime_ints(*number.as_integer_ratio())
+
+else:
+raise TypeError("argument should be a Rational instance or "
+"have the as_integer_ratio() method")
+
 @classmethod
 def from_float(cls, f):
 """Converts a finite float to a rational number, exactly.
diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py
index 4907f4093f52c9..98dccbec9566ac 100644
--- a/Lib/test/test_fractions.py
+++ b/Lib/test/test_fractions.py
@@ -283,6 +283,13 @@ def __repr__(self):
 class RectComplex(Rect, complex):
 pass
 
+class Ratio:
+def __init__(self, ratio):
+self._ratio = ratio
+def as_integer_ratio(self):
+return self._ratio
+
+
 class FractionTest(unittest.TestCase):
 
 def assertTypedEquals(self, expected, actual):
@@ -355,14 +362,9 @@ def testInitFromDecimal(self):
 self.assertRaises(OverflowError, F, Decimal('-inf'))
 
 def testInitFromIntegerRatio(self):
-class Ratio:
-def __init__(self, ratio):
-self._ratio = ratio
-def as_integer_ratio(self):
-return self._ratio
-
 self.assertEqual((7, 3), _components(F(Ratio((7, 3)
-errmsg = "argument should be a string or a number"
+errmsg = (r"argument should be a string or a Rational instance or "
+  r"have the as_integer_ratio\(\) method")
 # the type also has an "as_integer_ratio" attribute.
 self.assertRaisesRegex(TypeError, errmsg, F, Ratio)
 # bad ratio
@@ -388,6 +390,8 @@ class B(metacl

[Python-checkins] gh-121798: Add class method Decimal.from_number() (GH-121801)

2024-10-14 Thread serhiy-storchaka
https://github.com/python/cpython/commit/5217328f93f599755bd70418952392c54f705a71
commit: 5217328f93f599755bd70418952392c54f705a71
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2024-10-14T08:24:01Z
summary:

gh-121798: Add class method Decimal.from_number() (GH-121801)

It is an alternate constructor which only accepts a single numeric argument.
Unlike to Decimal.from_float() it accepts also Decimal.
Unlike to the standard constructor, it does not accept strings and tuples.

files:
A Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst
M Doc/library/decimal.rst
M Doc/whatsnew/3.14.rst
M Lib/_pydecimal.py
M Lib/test/test_decimal.py
M Modules/_decimal/_decimal.c
M Modules/_decimal/docstrings.h

diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index 916f17cadfaa7e..c9a3e448cad063 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -598,6 +598,23 @@ Decimal objects
 
   .. versionadded:: 3.1
 
+   .. classmethod:: from_number(number)
+
+  Alternative constructor that only accepts instances of
+  :class:`float`, :class:`int` or :class:`Decimal`, but not strings
+  or tuples.
+
+  .. doctest::
+
+  >>> Decimal.from_number(314)
+  Decimal('314')
+  >>> Decimal.from_number(0.1)
+  Decimal('0.155511151231257827021181583404541015625')
+  >>> Decimal.from_number(Decimal('3.14'))
+  Decimal('3.14')
+
+  .. versionadded:: 3.14
+
.. method:: fma(other, third, context=None)
 
   Fused multiply-add.  Return self*other+third with no rounding of the
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index b22d1bd1e99d4e..25e69a59bdec62 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -239,6 +239,12 @@ ctypes
   to help match a non-default ABI.
   (Contributed by Petr Viktorin in :gh:`97702`.)
 
+decimal
+---
+
+* Add alternative :class:`~decimal.Decimal` constructor
+  :meth:`Decimal.from_number() `.
+  (Contributed by Serhiy Storchaka in :gh:`121798`.)
 
 dis
 ---
diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index 75df3db262470b..5b60570c6c592a 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -582,6 +582,21 @@ def __new__(cls, value="0", context=None):
 
 raise TypeError("Cannot convert %r to Decimal" % value)
 
+@classmethod
+def from_number(cls, number):
+"""Converts a real number to a decimal number, exactly.
+
+>>> Decimal.from_number(314)  # int
+Decimal('314')
+>>> Decimal.from_number(0.1)  # float
+Decimal('0.155511151231257827021181583404541015625')
+>>> Decimal.from_number(Decimal('3.14'))  # another decimal instance
+Decimal('3.14')
+"""
+if isinstance(number, (int, Decimal, float)):
+return cls(number)
+raise TypeError("Cannot convert %r to Decimal" % number)
+
 @classmethod
 def from_float(cls, f):
 """Converts a float to a decimal number, exactly.
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index d1e7e69e7e951b..bc6c6427740949 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -812,6 +812,29 @@ def test_explicit_context_create_from_float(self):
 x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
 self.assertEqual(x, float(nc.create_decimal(x))) # roundtrip
 
+def test_from_number(self, cls=None):
+Decimal = self.decimal.Decimal
+if cls is None:
+cls = Decimal
+
+def check(arg, expected):
+d = cls.from_number(arg)
+self.assertIs(type(d), cls)
+self.assertEqual(d, expected)
+
+check(314, Decimal(314))
+check(3.14, Decimal.from_float(3.14))
+check(Decimal('3.14'), Decimal('3.14'))
+self.assertRaises(TypeError, cls.from_number, 3+4j)
+self.assertRaises(TypeError, cls.from_number, '314')
+self.assertRaises(TypeError, cls.from_number, (0, (3, 1, 4), 0))
+self.assertRaises(TypeError, cls.from_number, object())
+
+def test_from_number_subclass(self, cls=None):
+class DecimalSubclass(self.decimal.Decimal):
+pass
+self.test_from_number(DecimalSubclass)
+
 def test_unicode_digits(self):
 Decimal = self.decimal.Decimal
 
diff --git 
a/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst 
b/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst
new file mode 100644
index 00..5706e4bffeb4a1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-07-15-19-25-25.gh-issue-121798.GmuBDu.rst
@@ -0,0 +1,2 @@
+Add alternative :class:`~decimal.Decimal` constructor
+:meth:`Decimal.from_number() `.
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index a33c9793b5ad17..c564813036e504 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_d

[Python-checkins] gh-125139: use `_PyRecursiveMutex` in `_thread.RLock` (#125144)

2024-10-14 Thread kumaraditya303
https://github.com/python/cpython/commit/67f6e08147bc005e460d82fcce85bf5d56009cf5
commit: 67f6e08147bc005e460d82fcce85bf5d56009cf5
branch: main
author: Kumar Aditya 
committer: kumaraditya303 
date: 2024-10-14T14:06:31+05:30
summary:

gh-125139: use `_PyRecursiveMutex` in `_thread.RLock` (#125144)

files:
M Include/internal/pycore_lock.h
M Modules/_threadmodule.c
M Python/lock.c

diff --git a/Include/internal/pycore_lock.h b/Include/internal/pycore_lock.h
index cd7deda00c7bee..57cbce8f126aca 100644
--- a/Include/internal/pycore_lock.h
+++ b/Include/internal/pycore_lock.h
@@ -160,8 +160,9 @@ typedef struct {
 
 PyAPI_FUNC(int) _PyRecursiveMutex_IsLockedByCurrentThread(_PyRecursiveMutex 
*m);
 PyAPI_FUNC(void) _PyRecursiveMutex_Lock(_PyRecursiveMutex *m);
+extern PyLockStatus _PyRecursiveMutex_LockTimed(_PyRecursiveMutex *m, PyTime_t 
timeout, _PyLockFlags flags);
 PyAPI_FUNC(void) _PyRecursiveMutex_Unlock(_PyRecursiveMutex *m);
-
+extern int _PyRecursiveMutex_TryUnlock(_PyRecursiveMutex *m);
 
 // A readers-writer (RW) lock. The lock supports multiple concurrent readers or
 // a single writer. The lock is write-preferring: if a writer is waiting while
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 9617f9cafe76ff..d4408aa9e42d9d 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -726,11 +726,6 @@ lock_dealloc(PyObject *op)
 Py_DECREF(tp);
 }
 
-static inline PyLockStatus
-acquire_timed(PyThread_type_lock lock, PyTime_t timeout)
-{
-return PyThread_acquire_lock_timed_with_retries(lock, timeout);
-}
 
 static int
 lock_acquire_parse_args(PyObject *args, PyObject *kwds,
@@ -973,10 +968,7 @@ static PyType_Spec lock_type_spec = {
 
 typedef struct {
 PyObject_HEAD
-PyThread_type_lock rlock_lock;
-PyThread_ident_t rlock_owner;
-unsigned long rlock_count;
-PyObject *in_weakreflist;
+_PyRecursiveMutex lock;
 } rlockobject;
 
 static int
@@ -992,59 +984,26 @@ rlock_dealloc(PyObject *op)
 {
 rlockobject *self = (rlockobject*)op;
 PyObject_GC_UnTrack(self);
-if (self->in_weakreflist != NULL)
-PyObject_ClearWeakRefs((PyObject *) self);
-/* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
-   in rlock_new() */
-if (self->rlock_lock != NULL) {
-/* Unlock the lock so it's safe to free it */
-if (self->rlock_count > 0)
-PyThread_release_lock(self->rlock_lock);
-
-PyThread_free_lock(self->rlock_lock);
-}
+PyObject_ClearWeakRefs((PyObject *) self);
 PyTypeObject *tp = Py_TYPE(self);
 tp->tp_free(self);
 Py_DECREF(tp);
 }
 
-static bool
-rlock_is_owned_by(rlockobject *self, PyThread_ident_t tid)
-{
-PyThread_ident_t owner_tid =
-_Py_atomic_load_ullong_relaxed(&self->rlock_owner);
-return owner_tid == tid && self->rlock_count > 0;
-}
 
 static PyObject *
 rlock_acquire(PyObject *op, PyObject *args, PyObject *kwds)
 {
 rlockobject *self = (rlockobject*)op;
 PyTime_t timeout;
-PyThread_ident_t tid;
-PyLockStatus r = PY_LOCK_ACQUIRED;
 
-if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
+if (lock_acquire_parse_args(args, kwds, &timeout) < 0) {
 return NULL;
-
-tid = PyThread_get_thread_ident_ex();
-if (rlock_is_owned_by(self, tid)) {
-unsigned long count = self->rlock_count + 1;
-if (count <= self->rlock_count) {
-PyErr_SetString(PyExc_OverflowError,
-"Internal lock count overflowed");
-return NULL;
-}
-self->rlock_count = count;
-Py_RETURN_TRUE;
-}
-r = acquire_timed(self->rlock_lock, timeout);
-if (r == PY_LOCK_ACQUIRED) {
-assert(self->rlock_count == 0);
-_Py_atomic_store_ullong_relaxed(&self->rlock_owner, tid);
-self->rlock_count = 1;
 }
-else if (r == PY_LOCK_INTR) {
+
+PyLockStatus r = _PyRecursiveMutex_LockTimed(&self->lock, timeout,
+ _PY_LOCK_HANDLE_SIGNALS | 
_PY_LOCK_DETACH);
+if (r == PY_LOCK_INTR) {
 return NULL;
 }
 
@@ -1078,17 +1037,12 @@ static PyObject *
 rlock_release(PyObject *op, PyObject *Py_UNUSED(ignored))
 {
 rlockobject *self = (rlockobject*)op;
-PyThread_ident_t tid = PyThread_get_thread_ident_ex();
 
-if (!rlock_is_owned_by(self, tid)) {
+if (_PyRecursiveMutex_TryUnlock(&self->lock) < 0) {
 PyErr_SetString(PyExc_RuntimeError,
 "cannot release un-acquired lock");
 return NULL;
 }
-if (--self->rlock_count == 0) {
-_Py_atomic_store_ullong_relaxed(&self->rlock_owner, 0);
-PyThread_release_lock(self->rlock_lock);
-}
 Py_RETURN_NONE;
 }
 
@@ -1116,25 +1070,15 @@ rlock_acquire_restore(PyObject *op, PyObject *args)
 {
 rlockobject *self = (rlockobject*)op;
 PyThread_ident_t owner;
-unsigned long count;
-int r = 1;
+Py_ssize_t count;
 
-if (!PyArg_ParseTuple(args, "(k" 

[Python-checkins] GH-125323: Convert DECREF_INPUTS_AND_REUSE_FLOAT into a function that takes PyStackRefs. (GH-125439)

2024-10-14 Thread markshannon
https://github.com/python/cpython/commit/06ca33020e1168459fc6c3e0df93664daf801339
commit: 06ca33020e1168459fc6c3e0df93664daf801339
branch: main
author: Mark Shannon 
committer: markshannon 
date: 2024-10-14T14:18:57+01:00
summary:

GH-125323: Convert DECREF_INPUTS_AND_REUSE_FLOAT into a function that takes 
PyStackRefs. (GH-125439)

files:
M Include/internal/pycore_ceval.h
M Include/internal/pycore_opcode_metadata.h
M Include/internal/pycore_stackref.h
M Include/internal/pycore_uop_metadata.h
M Objects/floatobject.c
M Python/bytecodes.c
M Python/ceval_macros.h
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Tools/cases_generator/analyzer.py

diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h
index 594fbb1c8e443b..cff2b1f7114793 100644
--- a/Include/internal/pycore_ceval.h
+++ b/Include/internal/pycore_ceval.h
@@ -316,6 +316,8 @@ _Py_eval_breaker_bit_is_set(PyThreadState *tstate, 
uintptr_t bit)
 void _Py_set_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
 void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
 
+PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, 
_PyStackRef right, double value);
+
 
 #ifdef __cplusplus
 }
diff --git a/Include/internal/pycore_opcode_metadata.h 
b/Include/internal/pycore_opcode_metadata.h
index 8fec45b1e8d5c3..c18423476d3962 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1015,13 +1015,13 @@ extern const struct opcode_metadata 
_PyOpcode_opcode_metadata[266];
 #ifdef NEED_OPCODE_METADATA
 const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
 [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | 
HAS_ESCAPES_FLAG },
-[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | 
HAS_ERROR_FLAG },
 [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | 
HAS_ERROR_FLAG },
 [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | 
HAS_ERROR_FLAG },
 [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | 
HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG },
-[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | 
HAS_ERROR_FLAG },
 [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | 
HAS_ERROR_FLAG },
-[BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+[BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | 
HAS_ERROR_FLAG },
 [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | 
HAS_ERROR_FLAG },
 [BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
 [BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG 
},
diff --git a/Include/internal/pycore_stackref.h 
b/Include/internal/pycore_stackref.h
index 0e6410466b924b..588e57f6cd97e0 100644
--- a/Include/internal/pycore_stackref.h
+++ b/Include/internal/pycore_stackref.h
@@ -76,6 +76,13 @@ PyStackRef_AsPyObjectBorrow(_PyStackRef stackref)
 
 #define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == 
Py_TAG_DEFERRED)
 
+static inline PyObject *
+PyStackRef_NotDeferred_AsPyObject(_PyStackRef stackref)
+{
+assert(!PyStackRef_IsDeferred(stackref));
+return (PyObject *)stackref.bits;
+}
+
 static inline PyObject *
 PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
 {
diff --git a/Include/internal/pycore_uop_metadata.h 
b/Include/internal/pycore_uop_metadata.h
index fd41e9a5fe862b..2f0a7fb2f6e549 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -69,9 +69,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
 [_GUARD_BOTH_FLOAT] = HAS_EXIT_FLAG,
 [_GUARD_NOS_FLOAT] = HAS_EXIT_FLAG,
 [_GUARD_TOS_FLOAT] = HAS_EXIT_FLAG,
-[_BINARY_OP_MULTIPLY_FLOAT] = HAS_PURE_FLAG,
-[_BINARY_OP_ADD_FLOAT] = HAS_PURE_FLAG,
-[_BINARY_OP_SUBTRACT_FLOAT] = HAS_PURE_FLAG,
+[_BINARY_OP_MULTIPLY_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+[_BINARY_OP_ADD_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+[_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
 [_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG,
 [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
 [_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | 
HAS_ERROR_FLAG,
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index a48a210adee3b9..d66863febe8c86 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -134,6 +134,41 @@ PyFloat_FromDouble(double fval)
 return (PyObject *) op;
 }
 
+#ifdef Py_GIL_DISABLED
+
+PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef 
right, double value)
+{
+PyStackRef_CLOSE(left);
+PyStackRef_CLOSE(right);
+return PyFloat_FromDouble(value);
+}
+
+#else // Py_GIL_DISABLED
+
+PyObje

[Python-checkins] gh-124960: Fixed `barry_as_FLUFL` future flag does not work in new REPL (#124999)

2024-10-14 Thread ambv
https://github.com/python/cpython/commit/6a08a753b702ac63c9b6ac58dd204d1fe9662e9d
commit: 6a08a753b702ac63c9b6ac58dd204d1fe9662e9d
branch: main
author: Wulian 
committer: ambv 
date: 2024-10-14T15:53:50+02:00
summary:

gh-124960: Fixed `barry_as_FLUFL` future flag does not work in new REPL 
(#124999)

Co-authored-by: Nice Zombies 
Co-authored-by: Łukasz Langa 

files:
A Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst
M Lib/_pyrepl/console.py
M Lib/codeop.py
M Lib/test/test_pyrepl/test_interact.py

diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py
index 3e72a56807f6fb..03266c4dfc2dd8 100644
--- a/Lib/_pyrepl/console.py
+++ b/Lib/_pyrepl/console.py
@@ -174,7 +174,13 @@ def _excepthook(self, typ, value, tb):
 
 def runsource(self, source, filename="", symbol="single"):
 try:
-tree = ast.parse(source)
+tree = self.compile.compiler(
+source,
+filename,
+"exec",
+ast.PyCF_ONLY_AST,
+incomplete_input=False,
+)
 except (SyntaxError, OverflowError, ValueError):
 self.showsyntaxerror(filename, source=source)
 return False
@@ -185,7 +191,7 @@ def runsource(self, source, filename="", 
symbol="single"):
 the_symbol = symbol if stmt is last_stmt else "exec"
 item = wrapper([stmt])
 try:
-code = self.compile.compiler(item, filename, the_symbol, 
dont_inherit=True)
+code = self.compile.compiler(item, filename, the_symbol)
 except SyntaxError as e:
 if e.args[0] == "'await' outside function":
 python = os.path.basename(sys.executable)
diff --git a/Lib/codeop.py b/Lib/codeop.py
index a0276b52d484e3..adf000ba29f88c 100644
--- a/Lib/codeop.py
+++ b/Lib/codeop.py
@@ -44,6 +44,7 @@
 # Caveat emptor: These flags are undocumented on purpose and depending
 # on their effect outside the standard library is **unsupported**.
 PyCF_DONT_IMPLY_DEDENT = 0x200
+PyCF_ONLY_AST = 0x400
 PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000
 
 def _maybe_compile(compiler, source, filename, symbol):
@@ -109,12 +110,14 @@ class Compile:
 def __init__(self):
 self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT
 
-def __call__(self, source, filename, symbol, **kwargs):
-flags = self.flags
+def __call__(self, source, filename, symbol, flags=0, **kwargs):
+flags |= self.flags
 if kwargs.get('incomplete_input', True) is False:
 flags &= ~PyCF_DONT_IMPLY_DEDENT
 flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT
 codeob = compile(source, filename, symbol, flags, True)
+if flags & PyCF_ONLY_AST:
+return codeob  # this is an ast.Module in this case
 for feature in _features:
 if codeob.co_flags & feature.compiler_flag:
 self.flags |= feature.compiler_flag
diff --git a/Lib/test/test_pyrepl/test_interact.py 
b/Lib/test/test_pyrepl/test_interact.py
index b7adaffbac0e22..0c6df4e5dae869 100644
--- a/Lib/test/test_pyrepl/test_interact.py
+++ b/Lib/test/test_pyrepl/test_interact.py
@@ -119,13 +119,38 @@ def 
test_runsource_shows_syntax_error_for_failed_compilation(self):
 
 def test_no_active_future(self):
 console = InteractiveColoredConsole()
-source = "x: int = 1; print(__annotate__(1))"
+source = dedent("""\
+x: int = 1
+print(__annotate__(1))
+""")
 f = io.StringIO()
 with contextlib.redirect_stdout(f):
 result = console.runsource(source)
 self.assertFalse(result)
 self.assertEqual(f.getvalue(), "{'x': }\n")
 
+def test_future_annotations(self):
+console = InteractiveColoredConsole()
+source = dedent("""\
+from __future__ import annotations
+def g(x: int): ...
+print(g.__annotations__)
+""")
+f = io.StringIO()
+with contextlib.redirect_stdout(f):
+result = console.runsource(source)
+self.assertFalse(result)
+self.assertEqual(f.getvalue(), "{'x': 'int'}\n")
+
+def test_future_barry_as_flufl(self):
+console = InteractiveColoredConsole()
+f = io.StringIO()
+with contextlib.redirect_stdout(f):
+result = console.runsource("from __future__ import 
barry_as_FLUFL\n")
+result = console.runsource("""print("black" <> 'blue')\n""")
+self.assertFalse(result)
+self.assertEqual(f.getvalue(), "True\n")
+
 
 class TestMoreLines(unittest.TestCase):
 def test_invalid_syntax_single_line(self):
diff --git 
a/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst 
b/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst
new file mode 100644
index 00..332d6bb54d80c7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT

[Python-checkins] gh-112088: aclocal version is updated to 1.16.5 in docs (#125457)

2024-10-14 Thread vstinner
https://github.com/python/cpython/commit/45df264f3ffbc0893cbfd257131d3abe21043786
commit: 45df264f3ffbc0893cbfd257131d3abe21043786
branch: main
author: Mikhail Efimov 
committer: vstinner 
date: 2024-10-14T16:53:08+02:00
summary:

gh-112088: aclocal version is updated to 1.16.5 in docs (#125457)

files:
M Doc/using/configure.rst
M Doc/whatsnew/3.13.rst

diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst
index 4976418ba33cf8..10cdf2376229ff 100644
--- a/Doc/using/configure.rst
+++ b/Doc/using/configure.rst
@@ -29,7 +29,7 @@ Features and minimum versions required to build CPython:
 
 * Tcl/Tk 8.5.12 for the :mod:`tkinter` module.
 
-* Autoconf 2.71 and aclocal 1.16.4 are required to regenerate the
+* Autoconf 2.71 and aclocal 1.16.5 are required to regenerate the
   :file:`configure` script.
 
 .. versionchanged:: 3.1
@@ -56,7 +56,7 @@ Features and minimum versions required to build CPython:
Tcl/Tk version 8.5.12 is now required for the :mod:`tkinter` module.
 
 .. versionchanged:: 3.13
-   Autoconf 2.71, aclocal 1.16.4 and SQLite 3.15.2 are now required.
+   Autoconf 2.71, aclocal 1.16.5 and SQLite 3.15.2 are now required.
 
 See also :pep:`7` "Style Guide for C Code" and :pep:`11` "CPython platform
 support".
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index a2897097aaba57..f9e74a9b8ff9c6 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -2495,9 +2495,9 @@ Build Changes
 * Building CPython now requires a compiler with support for the C11 atomic
   library, GCC built-in atomic functions, or MSVC interlocked intrinsics.
 
-* Autoconf 2.71 and aclocal 1.16.4 are now required to regenerate
+* Autoconf 2.71 and aclocal 1.16.5 are now required to regenerate
   the :file:`configure` script.
-  (Contributed by Christian Heimes in :gh:`89886`.)
+  (Contributed by Christian Heimes in :gh:`89886` and by Victor Stinner in 
:gh:`112090`.)
 
 * SQLite 3.15.2 or newer is required to build
   the :mod:`sqlite3` extension module.

___
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-112088: aclocal version is updated to 1.16.5 in docs (GH-125457) (#125459)

2024-10-14 Thread vstinner
https://github.com/python/cpython/commit/6c81928ba75efb17e1b3287ccf9500835d51c841
commit: 6c81928ba75efb17e1b3287ccf9500835d51c841
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: vstinner 
date: 2024-10-14T15:02:06Z
summary:

[3.13] gh-112088: aclocal version is updated to 1.16.5 in docs (GH-125457) 
(#125459)

gh-112088: aclocal version is updated to 1.16.5 in docs (GH-125457)
(cherry picked from commit 45df264f3ffbc0893cbfd257131d3abe21043786)

Co-authored-by: Mikhail Efimov 

files:
M Doc/using/configure.rst
M Doc/whatsnew/3.13.rst

diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst
index 052289bd827366..d5a6ffb7bb334e 100644
--- a/Doc/using/configure.rst
+++ b/Doc/using/configure.rst
@@ -29,7 +29,7 @@ Features and minimum versions required to build CPython:
 
 * Tcl/Tk 8.5.12 for the :mod:`tkinter` module.
 
-* Autoconf 2.71 and aclocal 1.16.4 are required to regenerate the
+* Autoconf 2.71 and aclocal 1.16.5 are required to regenerate the
   :file:`configure` script.
 
 .. versionchanged:: 3.1
@@ -56,7 +56,7 @@ Features and minimum versions required to build CPython:
Tcl/Tk version 8.5.12 is now required for the :mod:`tkinter` module.
 
 .. versionchanged:: 3.13
-   Autoconf 2.71, aclocal 1.16.4 and SQLite 3.15.2 are now required.
+   Autoconf 2.71, aclocal 1.16.5 and SQLite 3.15.2 are now required.
 
 See also :pep:`7` "Style Guide for C Code" and :pep:`11` "CPython platform
 support".
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index a2897097aaba57..f9e74a9b8ff9c6 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -2495,9 +2495,9 @@ Build Changes
 * Building CPython now requires a compiler with support for the C11 atomic
   library, GCC built-in atomic functions, or MSVC interlocked intrinsics.
 
-* Autoconf 2.71 and aclocal 1.16.4 are now required to regenerate
+* Autoconf 2.71 and aclocal 1.16.5 are now required to regenerate
   the :file:`configure` script.
-  (Contributed by Christian Heimes in :gh:`89886`.)
+  (Contributed by Christian Heimes in :gh:`89886` and by Victor Stinner in 
:gh:`112090`.)
 
 * SQLite 3.15.2 or newer is required to build
   the :mod:`sqlite3` extension module.

___
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-86357: argparse: use str() consistently and explicitly to print choices (GH-117766) (GH-125432)

2024-10-14 Thread serhiy-storchaka
https://github.com/python/cpython/commit/21524eec48f5b1c807f185253e9350cfdd897ce0
commit: 21524eec48f5b1c807f185253e9350cfdd897ce0
branch: 3.12
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2024-10-14T07:04:44Z
summary:

[3.12] gh-86357: argparse: use str() consistently and explicitly to print 
choices (GH-117766) (GH-125432)

(cherry picked from commit 66b3922b97388c328c9bd8df050eef11c0261fae)

Signed-off-by: Jan Chren ~rindeal 
Co-authored-by: rindeal 

files:
A Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Lib/argparse.py b/Lib/argparse.py
index 0e13ea5860da97..22c9b07db18a4f 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -588,8 +588,7 @@ def _metavar_formatter(self, action, default_metavar):
 if action.metavar is not None:
 result = action.metavar
 elif action.choices is not None:
-choice_strs = [str(choice) for choice in action.choices]
-result = '{%s}' % ','.join(choice_strs)
+result = '{%s}' % ','.join(map(str, action.choices))
 else:
 result = default_metavar
 
@@ -637,8 +636,7 @@ def _expand_help(self, action):
 if hasattr(params[name], '__name__'):
 params[name] = params[name].__name__
 if params.get('choices') is not None:
-choices_str = ', '.join([str(c) for c in params['choices']])
-params['choices'] = choices_str
+params['choices'] = ', '.join(map(str, params['choices']))
 return self._get_help_string(action) % params
 
 def _iter_indented_subactions(self, action):
@@ -763,7 +761,7 @@ def _get_action_name(argument):
 elif argument.dest not in (None, SUPPRESS):
 return argument.dest
 elif argument.choices:
-return '{' + ','.join(argument.choices) + '}'
+return '{%s}' % ','.join(map(str, argument.choices))
 else:
 return None
 
@@ -2600,8 +2598,8 @@ def _check_value(self, action, value):
 if isinstance(choices, str):
 choices = iter(choices)
 if value not in choices:
-args = {'value': value,
-'choices': ', '.join(map(repr, action.choices))}
+args = {'value': str(value),
+'choices': ', '.join(map(str, action.choices))}
 msg = _('invalid choice: %(value)r (choose from %(choices)s)')
 raise ArgumentError(action, msg % args)
 
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 956c1cd505a96e..d8a4a00292d230 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -15,6 +15,7 @@
 import argparse
 import warnings
 
+from enum import StrEnum
 from test.support import os_helper
 from unittest import mock
 
@@ -1021,6 +1022,34 @@ class 
TestDisallowLongAbbreviationAllowsShortGroupingPrefix(ParserTestCase):
 ]
 
 
+class TestStrEnumChoices(TestCase):
+class Color(StrEnum):
+RED = "red"
+GREEN = "green"
+BLUE = "blue"
+
+def test_parse_enum_value(self):
+parser = argparse.ArgumentParser()
+parser.add_argument('--color', choices=self.Color)
+args = parser.parse_args(['--color', 'red'])
+self.assertEqual(args.color, self.Color.RED)
+
+def test_help_message_contains_enum_choices(self):
+parser = argparse.ArgumentParser()
+parser.add_argument('--color', choices=self.Color, help='Choose a 
color')
+self.assertIn('[--color {red,green,blue}]', parser.format_usage())
+self.assertIn('  --color {red,green,blue}', parser.format_help())
+
+def test_invalid_enum_value_raises_error(self):
+parser = argparse.ArgumentParser(exit_on_error=False)
+parser.add_argument('--color', choices=self.Color)
+self.assertRaisesRegex(
+argparse.ArgumentError,
+r"invalid choice: 'yellow' \(choose from red, green, blue\)",
+parser.parse_args,
+['--color', 'yellow'],
+)
+
 # 
 # Positional tests
 # 
@@ -2422,7 +2451,7 @@ def 
test_wrong_argument_subparsers_no_destination_error(self):
 parser.parse_args(('baz',))
 self.assertRegex(
 excinfo.exception.stderr,
-r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from 
'foo', 'bar'\)\n$"
+r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from 
foo, bar\)\n$"
 )
 
 def test_optional_subparsers(self):
diff --git 
a/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst 
b/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst
new file mode 100644
index 00..d090f931f0238d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst
@@ -0,0 +1 @@
+Always use :func:`str` to print ``choices`` in :mod:`argparse`.


[Python-checkins] [3.13] gh-86357: argparse: use str() consistently and explicitly to print choices (GH-117766) (GH-125431)

2024-10-14 Thread serhiy-storchaka
https://github.com/python/cpython/commit/d3d306a9d63e879d4eac42694b94ed4a7f440332
commit: d3d306a9d63e879d4eac42694b94ed4a7f440332
branch: 3.13
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2024-10-14T07:09:06Z
summary:

[3.13] gh-86357: argparse: use str() consistently and explicitly to print 
choices (GH-117766) (GH-125431)

(cherry picked from commit 66b3922b97388c328c9bd8df050eef11c0261fae)

Signed-off-by: Jan Chren ~rindeal 
Co-authored-by: rindeal 

files:
A Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Lib/argparse.py b/Lib/argparse.py
index 663e40c8e2d7a6..395bb1cd13b966 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -547,8 +547,7 @@ def _metavar_formatter(self, action, default_metavar):
 if action.metavar is not None:
 result = action.metavar
 elif action.choices is not None:
-choice_strs = [str(choice) for choice in action.choices]
-result = '{%s}' % ','.join(choice_strs)
+result = '{%s}' % ','.join(map(str, action.choices))
 else:
 result = default_metavar
 
@@ -596,8 +595,7 @@ def _expand_help(self, action):
 if hasattr(params[name], '__name__'):
 params[name] = params[name].__name__
 if params.get('choices') is not None:
-choices_str = ', '.join([str(c) for c in params['choices']])
-params['choices'] = choices_str
+params['choices'] = ', '.join(map(str, params['choices']))
 return self._get_help_string(action) % params
 
 def _iter_indented_subactions(self, action):
@@ -714,7 +712,7 @@ def _get_action_name(argument):
 elif argument.dest not in (None, SUPPRESS):
 return argument.dest
 elif argument.choices:
-return '{' + ','.join(argument.choices) + '}'
+return '{%s}' % ','.join(map(str, argument.choices))
 else:
 return None
 
@@ -2595,8 +2593,8 @@ def _check_value(self, action, value):
 if isinstance(choices, str):
 choices = iter(choices)
 if value not in choices:
-args = {'value': value,
-'choices': ', '.join(map(repr, action.choices))}
+args = {'value': str(value),
+'choices': ', '.join(map(str, action.choices))}
 msg = _('invalid choice: %(value)r (choose from %(choices)s)')
 raise ArgumentError(action, msg % args)
 
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 373c04b61a2615..77af8642c077a0 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -15,6 +15,7 @@
 import argparse
 import warnings
 
+from enum import StrEnum
 from test.support import os_helper, captured_stderr
 from unittest import mock
 
@@ -1021,6 +1022,34 @@ class 
TestDisallowLongAbbreviationAllowsShortGroupingPrefix(ParserTestCase):
 ]
 
 
+class TestStrEnumChoices(TestCase):
+class Color(StrEnum):
+RED = "red"
+GREEN = "green"
+BLUE = "blue"
+
+def test_parse_enum_value(self):
+parser = argparse.ArgumentParser()
+parser.add_argument('--color', choices=self.Color)
+args = parser.parse_args(['--color', 'red'])
+self.assertEqual(args.color, self.Color.RED)
+
+def test_help_message_contains_enum_choices(self):
+parser = argparse.ArgumentParser()
+parser.add_argument('--color', choices=self.Color, help='Choose a 
color')
+self.assertIn('[--color {red,green,blue}]', parser.format_usage())
+self.assertIn('  --color {red,green,blue}', parser.format_help())
+
+def test_invalid_enum_value_raises_error(self):
+parser = argparse.ArgumentParser(exit_on_error=False)
+parser.add_argument('--color', choices=self.Color)
+self.assertRaisesRegex(
+argparse.ArgumentError,
+r"invalid choice: 'yellow' \(choose from red, green, blue\)",
+parser.parse_args,
+['--color', 'yellow'],
+)
+
 # 
 # Positional tests
 # 
@@ -2486,7 +2515,7 @@ def 
test_wrong_argument_subparsers_no_destination_error(self):
 parser.parse_args(('baz',))
 self.assertRegex(
 excinfo.exception.stderr,
-r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from 
'foo', 'bar'\)\n$"
+r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from 
foo, bar\)\n$"
 )
 
 def test_optional_subparsers(self):
diff --git 
a/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst 
b/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst
new file mode 100644
index 00..d090f931f0238d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-04-19-05-58-50.gh-issue-117766.J3xepp.rst
@@ -0,0 +1 @@
+Always use :func:`str` to print ``choices`` in :mod:`arg

[Python-checkins] gh-111178: fix USAN failures for `partialobject` (#124733)

2024-10-14 Thread vstinner
https://github.com/python/cpython/commit/c77121e9f19702b1ab280299394e38e8f15c0fd3
commit: c77121e9f19702b1ab280299394e38e8f15c0fd3
branch: main
author: Bénédikt Tran <[email protected]>
committer: vstinner 
date: 2024-10-14T16:23:05+02:00
summary:

gh-78: fix USAN failures for `partialobject` (#124733)

files:
M Modules/_functoolsmodule.c

diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index 4ab3adc0fe44cc..802b1cf792c555 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -144,10 +144,13 @@ typedef struct {
 vectorcallfunc vectorcall;
 } partialobject;
 
+// cast a PyObject pointer PTR to a partialobject pointer (no type checks)
+#define _PyPartialObject_CAST(PTR)  ((partialobject *)(PTR))
+
 static void partial_setvectorcall(partialobject *pto);
 static struct PyModuleDef _functools_module;
 static PyObject *
-partial_call(partialobject *pto, PyObject *args, PyObject *kwargs);
+partial_call(PyObject *pto, PyObject *args, PyObject *kwargs);
 
 static inline _functools_state *
 get_functools_state_by_type(PyTypeObject *type)
@@ -307,8 +310,9 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject 
*kw)
 }
 
 static int
-partial_clear(partialobject *pto)
+partial_clear(PyObject *self)
 {
+partialobject *pto = _PyPartialObject_CAST(self);
 Py_CLEAR(pto->fn);
 Py_CLEAR(pto->args);
 Py_CLEAR(pto->kw);
@@ -317,8 +321,9 @@ partial_clear(partialobject *pto)
 }
 
 static int
-partial_traverse(partialobject *pto, visitproc visit, void *arg)
+partial_traverse(PyObject *self, visitproc visit, void *arg)
 {
+partialobject *pto = _PyPartialObject_CAST(self);
 Py_VISIT(Py_TYPE(pto));
 Py_VISIT(pto->fn);
 Py_VISIT(pto->args);
@@ -328,16 +333,16 @@ partial_traverse(partialobject *pto, visitproc visit, 
void *arg)
 }
 
 static void
-partial_dealloc(partialobject *pto)
+partial_dealloc(PyObject *self)
 {
-PyTypeObject *tp = Py_TYPE(pto);
+PyTypeObject *tp = Py_TYPE(self);
 /* bpo-31095: UnTrack is needed before calling any callbacks */
-PyObject_GC_UnTrack(pto);
-if (pto->weakreflist != NULL) {
-PyObject_ClearWeakRefs((PyObject *) pto);
+PyObject_GC_UnTrack(self);
+if (_PyPartialObject_CAST(self)->weakreflist != NULL) {
+PyObject_ClearWeakRefs(self);
 }
-(void)partial_clear(pto);
-tp->tp_free(pto);
+(void)partial_clear(self);
+tp->tp_free(self);
 Py_DECREF(tp);
 }
 
@@ -360,14 +365,14 @@ partial_vectorcall_fallback(PyThreadState *tstate, 
partialobject *pto,
 {
 pto->vectorcall = NULL;
 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
-return _PyObject_MakeTpCall(tstate, (PyObject *)pto,
-args, nargs, kwnames);
+return _PyObject_MakeTpCall(tstate, (PyObject *)pto, args, nargs, kwnames);
 }
 
 static PyObject *
-partial_vectorcall(partialobject *pto, PyObject *const *args,
+partial_vectorcall(PyObject *self, PyObject *const *args,
size_t nargsf, PyObject *kwnames)
 {
+partialobject *pto = _PyPartialObject_CAST(self);;
 PyThreadState *tstate = _PyThreadState_GET();
 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
 
@@ -468,15 +473,16 @@ partial_setvectorcall(partialobject *pto)
  * but that is unlikely (why use partial without arguments?),
  * so we don't optimize that */
 else {
-pto->vectorcall = (vectorcallfunc)partial_vectorcall;
+pto->vectorcall = partial_vectorcall;
 }
 }
 
 
 // Not converted to argument clinic, because of `*args, **kwargs` arguments.
 static PyObject *
-partial_call(partialobject *pto, PyObject *args, PyObject *kwargs)
+partial_call(PyObject *self, PyObject *args, PyObject *kwargs)
 {
+partialobject *pto = _PyPartialObject_CAST(self);
 assert(PyCallable_Check(pto->fn));
 assert(PyTuple_Check(pto->args));
 assert(PyDict_Check(pto->kw));
@@ -587,8 +593,9 @@ static PyGetSetDef partial_getsetlist[] = {
 };
 
 static PyObject *
-partial_repr(partialobject *pto)
+partial_repr(PyObject *self)
 {
+partialobject *pto = _PyPartialObject_CAST(self);
 PyObject *result = NULL;
 PyObject *arglist;
 PyObject *mod;
@@ -597,7 +604,7 @@ partial_repr(partialobject *pto)
 PyObject *key, *value;
 int status;
 
-status = Py_ReprEnter((PyObject *)pto);
+status = Py_ReprEnter(self);
 if (status != 0) {
 if (status < 0)
 return NULL;
@@ -608,7 +615,7 @@ partial_repr(partialobject *pto)
 if (arglist == NULL)
 goto done;
 /* Pack positional arguments */
-assert (PyTuple_Check(pto->args));
+assert(PyTuple_Check(pto->args));
 n = PyTuple_GET_SIZE(pto->args);
 for (i = 0; i < n; i++) {
 Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist,
@@ -643,11 +650,11 @@ partial_repr(partialobject *pto)
 Py_DECREF(arglist);
 
  done:
-Py_ReprLeave((PyObject *)pto);
+Py_ReprLeave(self);
 return result;
  error:
 Py_DECREF

[Python-checkins] [3.13] gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (GH-124959) (#125463)

2024-10-14 Thread 1st1
https://github.com/python/cpython/commit/4e08c9829269525f097407ef017ebffd165e4ea9
commit: 4e08c9829269525f097407ef017ebffd165e4ea9
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: 1st1 
date: 2024-10-14T15:45:49Z
summary:

[3.13] gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (GH-124959) 
(#125463)

gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (GH-124959)
(cherry picked from commit d5dbbf4372cd3dbf3eead1cc70ddc4261c061fd9)

Co-authored-by: Thomas Grainger 

files:
A Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst
M Lib/asyncio/futures.py
M Lib/asyncio/taskgroups.py
M Lib/test/test_asyncio/test_futures.py
M Lib/test/test_asyncio/test_taskgroups.py

diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 9c1b5e49e1a70b..51932639097bbd 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -191,8 +191,7 @@ def result(self):
 the future is done and has an exception set, this exception is raised.
 """
 if self._state == _CANCELLED:
-exc = self._make_cancelled_error()
-raise exc
+raise self._make_cancelled_error()
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Result is not ready.')
 self.__log_traceback = False
@@ -209,8 +208,7 @@ def exception(self):
 InvalidStateError.
 """
 if self._state == _CANCELLED:
-exc = self._make_cancelled_error()
-raise exc
+raise self._make_cancelled_error()
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Exception is not set.')
 self.__log_traceback = False
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index f2ee9648c43876..9fa772ca9d02cc 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -66,6 +66,20 @@ async def __aenter__(self):
 return self
 
 async def __aexit__(self, et, exc, tb):
+tb = None
+try:
+return await self._aexit(et, exc)
+finally:
+# Exceptions are heavy objects that can have object
+# cycles (bad for GC); let's not keep a reference to
+# a bunch of them. It would be nicer to use a try/finally
+# in __aexit__ directly but that introduced some diff noise
+self._parent_task = None
+self._errors = None
+self._base_error = None
+exc = None
+
+async def _aexit(self, et, exc):
 self._exiting = True
 
 if (exc is not None and
@@ -122,7 +136,10 @@ async def __aexit__(self, et, exc, tb):
 assert not self._tasks
 
 if self._base_error is not None:
-raise self._base_error
+try:
+raise self._base_error
+finally:
+exc = None
 
 if self._parent_cancel_requested:
 # If this flag is set we *must* call uncancel().
@@ -133,8 +150,14 @@ async def __aexit__(self, et, exc, tb):
 
 # Propagate CancelledError if there is one, except if there
 # are other errors -- those have priority.
-if propagate_cancellation_error is not None and not self._errors:
-raise propagate_cancellation_error
+try:
+if propagate_cancellation_error is not None and not self._errors:
+try:
+raise propagate_cancellation_error
+finally:
+exc = None
+finally:
+propagate_cancellation_error = None
 
 if et is not None and not issubclass(et, exceptions.CancelledError):
 self._errors.append(exc)
@@ -146,14 +169,14 @@ async def __aexit__(self, et, exc, tb):
 if self._parent_task.cancelling():
 self._parent_task.uncancel()
 self._parent_task.cancel()
-# Exceptions are heavy objects that can have object
-# cycles (bad for GC); let's not keep a reference to
-# a bunch of them.
 try:
-me = BaseExceptionGroup('unhandled errors in a TaskGroup', 
self._errors)
-raise me from None
+raise BaseExceptionGroup(
+'unhandled errors in a TaskGroup',
+self._errors,
+) from None
 finally:
-self._errors = None
+exc = None
+
 
 def create_task(self, coro, *, name=None, context=None):
 """Create a new task in this group and return it.
diff --git a/Lib/test/test_asyncio/test_futures.py 
b/Lib/test/test_asyncio/test_futures.py
index 2417712a9c9b64..32e7b5d9047c06 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -659,6 +659,28 @@ def __del__(self):
 fut = self._new_future(loop=self.loop)
 fut.set_result(Evil())
 
+de

[Python-checkins] [3.13] gh-125461: Remove Python 2 from identifiers in doc (GH-125462) (GH-125464)

2024-10-14 Thread willingc
https://github.com/python/cpython/commit/7966c7d69e43d2b946c5933f5249091466ba1f5e
commit: 7966c7d69e43d2b946c5933f5249091466ba1f5e
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: willingc 
date: 2024-10-14T08:49:35-07:00
summary:

[3.13] gh-125461: Remove Python 2 from identifiers in doc (GH-125462) 
(GH-125464)

gh-125461: Remove Python 2 from identifiers in doc (GH-125462)

Remove Python 2 from identifiers in doc
(cherry picked from commit 5dac0dceda9097d46a0b5a6ad7c927e002c6c7a5)

Co-authored-by: Paul Hoffman 

files:
M Doc/reference/lexical_analysis.rst

diff --git a/Doc/reference/lexical_analysis.rst 
b/Doc/reference/lexical_analysis.rst
index c2f5f145bb22b2..bffef9db8fb632 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -284,11 +284,10 @@ UAX-31, with elaboration and changes as defined below; 
see also :pep:`3131` for
 further details.
 
 Within the ASCII range (U+0001..U+007F), the valid characters for identifiers
-are the same as in Python 2.x: the uppercase and lowercase letters ``A`` 
through
+include the uppercase and lowercase letters ``A`` through
 ``Z``, the underscore ``_`` and, except for the first character, the digits
 ``0`` through ``9``.
-
-Python 3.0 introduces additional characters from outside the ASCII range (see
+Python 3.0 introduced additional characters from outside the ASCII range (see
 :pep:`3131`).  For these characters, the classification uses the version of the
 Unicode Character Database as included in the :mod:`unicodedata` module.
 

___
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-125461: Remove Python 2 from identifiers in doc (GH-125462) (#125465)

2024-10-14 Thread willingc
https://github.com/python/cpython/commit/f1a6f687774ca09255c48d76deb060bd09c8e1ca
commit: f1a6f687774ca09255c48d76deb060bd09c8e1ca
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: willingc 
date: 2024-10-14T08:49:56-07:00
summary:

[3.12] gh-125461: Remove Python 2 from identifiers in doc (GH-125462) (#125465)

gh-125461: Remove Python 2 from identifiers in doc (GH-125462)

Remove Python 2 from identifiers in doc
(cherry picked from commit 5dac0dceda9097d46a0b5a6ad7c927e002c6c7a5)

Co-authored-by: Paul Hoffman 

files:
M Doc/reference/lexical_analysis.rst

diff --git a/Doc/reference/lexical_analysis.rst 
b/Doc/reference/lexical_analysis.rst
index cfae01ba97a555..41d8fbaee97750 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -284,11 +284,10 @@ UAX-31, with elaboration and changes as defined below; 
see also :pep:`3131` for
 further details.
 
 Within the ASCII range (U+0001..U+007F), the valid characters for identifiers
-are the same as in Python 2.x: the uppercase and lowercase letters ``A`` 
through
+include the uppercase and lowercase letters ``A`` through
 ``Z``, the underscore ``_`` and, except for the first character, the digits
 ``0`` through ``9``.
-
-Python 3.0 introduces additional characters from outside the ASCII range (see
+Python 3.0 introduced additional characters from outside the ASCII range (see
 :pep:`3131`).  For these characters, the classification uses the version of the
 Unicode Character Database as included in the :mod:`unicodedata` module.
 

___
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-119786: [doc] broken link and typo fix in interpreter_definition.md (#125455)

2024-10-14 Thread iritkatriel
https://github.com/python/cpython/commit/187580d95c8339a3b6e2b012f98d86101c346cfa
commit: 187580d95c8339a3b6e2b012f98d86101c346cfa
branch: main
author: Mikhail Efimov 
committer: iritkatriel <[email protected]>
date: 2024-10-14T17:24:54Z
summary:

gh-119786: [doc] broken link and typo fix in interpreter_definition.md  
(#125455)

files:
M InternalDocs/README.md
M Tools/cases_generator/interpreter_definition.md

diff --git a/InternalDocs/README.md b/InternalDocs/README.md
index 805e2f97937e1e..0a6ecf899458ed 100644
--- a/InternalDocs/README.md
+++ b/InternalDocs/README.md
@@ -11,6 +11,8 @@ The core dev team attempts to keep this documentation up to 
date. If
 it is not, please report that through the
 [issue tracker](https://github.com/python/cpython/issues).
 
+Index:
+-
 
 [Guide to the parser](parser.md)
 
diff --git a/Tools/cases_generator/interpreter_definition.md 
b/Tools/cases_generator/interpreter_definition.md
index ba09931c541646..6cf36f343d5fa7 100644
--- a/Tools/cases_generator/interpreter_definition.md
+++ b/Tools/cases_generator/interpreter_definition.md
@@ -74,7 +74,7 @@ We update it as the need arises.
 ### Syntax
 
 Each op definition has a kind, a name, a stack and instruction stream effect,
-and a piece of C code describing its semantics::
+and a piece of C code describing its semantics:
 
 ```
   file:
@@ -245,7 +245,8 @@ The same is true for all members of a pseudo instruction
 
 ## Examples
 
-(Another source of examples can be found in the [tests](test_generator.py).)
+(Another source of examples can be found in the
+[tests](https://github.com/python/cpython/blob/main/Lib/test/test_generated_cases.py).)
 
 Some examples:
 

___
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-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#12… (#125476)

2024-10-14 Thread kumaraditya303
https://github.com/python/cpython/commit/e99650b80ace3893c2a80b3f2a4aca99cb305191
commit: e99650b80ace3893c2a80b3f2a4aca99cb305191
branch: main
author: Kirill Podoprigora 
committer: kumaraditya303 
date: 2024-10-14T17:59:13Z
summary:

gh-125472: Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles 
(#12… (#125476)

Revert "gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#124959)"

This reverts commit d5dbbf4372cd3dbf3eead1cc70ddc4261c061fd9.

files:
D Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst
M Lib/asyncio/futures.py
M Lib/asyncio/taskgroups.py
M Lib/test/test_asyncio/test_futures.py
M Lib/test/test_asyncio/test_taskgroups.py

diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index c95fce035cd548..5f6fa2348726cf 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -190,7 +190,8 @@ def result(self):
 the future is done and has an exception set, this exception is raised.
 """
 if self._state == _CANCELLED:
-raise self._make_cancelled_error()
+exc = self._make_cancelled_error()
+raise exc
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Result is not ready.')
 self.__log_traceback = False
@@ -207,7 +208,8 @@ def exception(self):
 InvalidStateError.
 """
 if self._state == _CANCELLED:
-raise self._make_cancelled_error()
+exc = self._make_cancelled_error()
+raise exc
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Exception is not set.')
 self.__log_traceback = False
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index 9fa772ca9d02cc..f2ee9648c43876 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -66,20 +66,6 @@ async def __aenter__(self):
 return self
 
 async def __aexit__(self, et, exc, tb):
-tb = None
-try:
-return await self._aexit(et, exc)
-finally:
-# Exceptions are heavy objects that can have object
-# cycles (bad for GC); let's not keep a reference to
-# a bunch of them. It would be nicer to use a try/finally
-# in __aexit__ directly but that introduced some diff noise
-self._parent_task = None
-self._errors = None
-self._base_error = None
-exc = None
-
-async def _aexit(self, et, exc):
 self._exiting = True
 
 if (exc is not None and
@@ -136,10 +122,7 @@ async def _aexit(self, et, exc):
 assert not self._tasks
 
 if self._base_error is not None:
-try:
-raise self._base_error
-finally:
-exc = None
+raise self._base_error
 
 if self._parent_cancel_requested:
 # If this flag is set we *must* call uncancel().
@@ -150,14 +133,8 @@ async def _aexit(self, et, exc):
 
 # Propagate CancelledError if there is one, except if there
 # are other errors -- those have priority.
-try:
-if propagate_cancellation_error is not None and not self._errors:
-try:
-raise propagate_cancellation_error
-finally:
-exc = None
-finally:
-propagate_cancellation_error = None
+if propagate_cancellation_error is not None and not self._errors:
+raise propagate_cancellation_error
 
 if et is not None and not issubclass(et, exceptions.CancelledError):
 self._errors.append(exc)
@@ -169,14 +146,14 @@ async def _aexit(self, et, exc):
 if self._parent_task.cancelling():
 self._parent_task.uncancel()
 self._parent_task.cancel()
+# Exceptions are heavy objects that can have object
+# cycles (bad for GC); let's not keep a reference to
+# a bunch of them.
 try:
-raise BaseExceptionGroup(
-'unhandled errors in a TaskGroup',
-self._errors,
-) from None
+me = BaseExceptionGroup('unhandled errors in a TaskGroup', 
self._errors)
+raise me from None
 finally:
-exc = None
-
+self._errors = None
 
 def create_task(self, coro, *, name=None, context=None):
 """Create a new task in this group and return it.
diff --git a/Lib/test/test_asyncio/test_futures.py 
b/Lib/test/test_asyncio/test_futures.py
index c566b28adb2408..458b70451a306a 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -659,28 +659,6 @@ def __del__(self):
 fut = self._new_future(loop=self.loop)
 fut.set_result(Evil())
 
-def test_future_cancelled_result_refcycles(self):
-f = self._new_future(loop=self.lo

[Python-checkins] [3.13] gh-124960: Fixed `barry_as_FLUFL` future flag does not work in new REPL (#124999) (#125475)

2024-10-14 Thread ambv
https://github.com/python/cpython/commit/d54dbd62cc9dae9ddee7a1179fb26ccdd4e409dc
commit: d54dbd62cc9dae9ddee7a1179fb26ccdd4e409dc
branch: 3.13
author: Nice Zombies 
committer: ambv 
date: 2024-10-14T20:00:45+02:00
summary:

[3.13] gh-124960: Fixed `barry_as_FLUFL` future flag does not work in new REPL 
(#124999) (#125475)

gh-124960: Fixed `barry_as_FLUFL` future flag does not work in new REPL 
(#124999)

Co-authored-by: Wulian 
Co-authored-by: Nice Zombies 
Co-authored-by: Łukasz Langa 
(cherry picked from commit 6a08a753b702ac63c9b6ac58dd204d1fe9662e9d)

files:
A Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst
M Lib/_pyrepl/console.py
M Lib/codeop.py
M Lib/test/test_pyrepl/test_interact.py

diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py
index 3e72a56807f6fb..03266c4dfc2dd8 100644
--- a/Lib/_pyrepl/console.py
+++ b/Lib/_pyrepl/console.py
@@ -174,7 +174,13 @@ def _excepthook(self, typ, value, tb):
 
 def runsource(self, source, filename="", symbol="single"):
 try:
-tree = ast.parse(source)
+tree = self.compile.compiler(
+source,
+filename,
+"exec",
+ast.PyCF_ONLY_AST,
+incomplete_input=False,
+)
 except (SyntaxError, OverflowError, ValueError):
 self.showsyntaxerror(filename, source=source)
 return False
@@ -185,7 +191,7 @@ def runsource(self, source, filename="", 
symbol="single"):
 the_symbol = symbol if stmt is last_stmt else "exec"
 item = wrapper([stmt])
 try:
-code = self.compile.compiler(item, filename, the_symbol, 
dont_inherit=True)
+code = self.compile.compiler(item, filename, the_symbol)
 except SyntaxError as e:
 if e.args[0] == "'await' outside function":
 python = os.path.basename(sys.executable)
diff --git a/Lib/codeop.py b/Lib/codeop.py
index a0276b52d484e3..adf000ba29f88c 100644
--- a/Lib/codeop.py
+++ b/Lib/codeop.py
@@ -44,6 +44,7 @@
 # Caveat emptor: These flags are undocumented on purpose and depending
 # on their effect outside the standard library is **unsupported**.
 PyCF_DONT_IMPLY_DEDENT = 0x200
+PyCF_ONLY_AST = 0x400
 PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000
 
 def _maybe_compile(compiler, source, filename, symbol):
@@ -109,12 +110,14 @@ class Compile:
 def __init__(self):
 self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT
 
-def __call__(self, source, filename, symbol, **kwargs):
-flags = self.flags
+def __call__(self, source, filename, symbol, flags=0, **kwargs):
+flags |= self.flags
 if kwargs.get('incomplete_input', True) is False:
 flags &= ~PyCF_DONT_IMPLY_DEDENT
 flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT
 codeob = compile(source, filename, symbol, flags, True)
+if flags & PyCF_ONLY_AST:
+return codeob  # this is an ast.Module in this case
 for feature in _features:
 if codeob.co_flags & feature.compiler_flag:
 self.flags |= feature.compiler_flag
diff --git a/Lib/test/test_pyrepl/test_interact.py 
b/Lib/test/test_pyrepl/test_interact.py
index e71ab419570a86..b746674b9ff889 100644
--- a/Lib/test/test_pyrepl/test_interact.py
+++ b/Lib/test/test_pyrepl/test_interact.py
@@ -119,13 +119,38 @@ def 
test_runsource_shows_syntax_error_for_failed_compilation(self):
 
 def test_no_active_future(self):
 console = InteractiveColoredConsole()
-source = "x: int = 1; print(__annotations__)"
+source = dedent("""\
+x: int = 1
+print(__annotations__)
+""")
 f = io.StringIO()
 with contextlib.redirect_stdout(f):
 result = console.runsource(source)
 self.assertFalse(result)
 self.assertEqual(f.getvalue(), "{'x': }\n")
 
+def test_future_annotations(self):
+console = InteractiveColoredConsole()
+source = dedent("""\
+from __future__ import annotations
+def g(x: int): ...
+print(g.__annotations__)
+""")
+f = io.StringIO()
+with contextlib.redirect_stdout(f):
+result = console.runsource(source)
+self.assertFalse(result)
+self.assertEqual(f.getvalue(), "{'x': 'int'}\n")
+
+def test_future_barry_as_flufl(self):
+console = InteractiveColoredConsole()
+f = io.StringIO()
+with contextlib.redirect_stdout(f):
+result = console.runsource("from __future__ import 
barry_as_FLUFL\n")
+result = console.runsource("""print("black" <> 'blue')\n""")
+self.assertFalse(result)
+self.assertEqual(f.getvalue(), "True\n")
+
 
 class TestMoreLines(unittest.TestCase):
 def test_invalid_syntax_single_line(self):
diff --git 
a/Misc/NEWS.d/next/Library/2024-10-05-15-49-53.gh-issue-124960.Bol9hT.rst 
b/Misc/NEWS.d/next/

[Python-checkins] gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#124959)

2024-10-14 Thread 1st1
https://github.com/python/cpython/commit/d5dbbf4372cd3dbf3eead1cc70ddc4261c061fd9
commit: d5dbbf4372cd3dbf3eead1cc70ddc4261c061fd9
branch: main
author: Thomas Grainger 
committer: 1st1 
date: 2024-10-14T08:19:56-07:00
summary:

gh-124958: fix asyncio.TaskGroup and _PyFuture refcycles (#124959)

files:
A Misc/NEWS.d/next/Library/2024-10-04-08-46-00.gh-issue-124958.rea9-x.rst
M Lib/asyncio/futures.py
M Lib/asyncio/taskgroups.py
M Lib/test/test_asyncio/test_futures.py
M Lib/test/test_asyncio/test_taskgroups.py

diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 5f6fa2348726cf..c95fce035cd548 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -190,8 +190,7 @@ def result(self):
 the future is done and has an exception set, this exception is raised.
 """
 if self._state == _CANCELLED:
-exc = self._make_cancelled_error()
-raise exc
+raise self._make_cancelled_error()
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Result is not ready.')
 self.__log_traceback = False
@@ -208,8 +207,7 @@ def exception(self):
 InvalidStateError.
 """
 if self._state == _CANCELLED:
-exc = self._make_cancelled_error()
-raise exc
+raise self._make_cancelled_error()
 if self._state != _FINISHED:
 raise exceptions.InvalidStateError('Exception is not set.')
 self.__log_traceback = False
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index f2ee9648c43876..9fa772ca9d02cc 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -66,6 +66,20 @@ async def __aenter__(self):
 return self
 
 async def __aexit__(self, et, exc, tb):
+tb = None
+try:
+return await self._aexit(et, exc)
+finally:
+# Exceptions are heavy objects that can have object
+# cycles (bad for GC); let's not keep a reference to
+# a bunch of them. It would be nicer to use a try/finally
+# in __aexit__ directly but that introduced some diff noise
+self._parent_task = None
+self._errors = None
+self._base_error = None
+exc = None
+
+async def _aexit(self, et, exc):
 self._exiting = True
 
 if (exc is not None and
@@ -122,7 +136,10 @@ async def __aexit__(self, et, exc, tb):
 assert not self._tasks
 
 if self._base_error is not None:
-raise self._base_error
+try:
+raise self._base_error
+finally:
+exc = None
 
 if self._parent_cancel_requested:
 # If this flag is set we *must* call uncancel().
@@ -133,8 +150,14 @@ async def __aexit__(self, et, exc, tb):
 
 # Propagate CancelledError if there is one, except if there
 # are other errors -- those have priority.
-if propagate_cancellation_error is not None and not self._errors:
-raise propagate_cancellation_error
+try:
+if propagate_cancellation_error is not None and not self._errors:
+try:
+raise propagate_cancellation_error
+finally:
+exc = None
+finally:
+propagate_cancellation_error = None
 
 if et is not None and not issubclass(et, exceptions.CancelledError):
 self._errors.append(exc)
@@ -146,14 +169,14 @@ async def __aexit__(self, et, exc, tb):
 if self._parent_task.cancelling():
 self._parent_task.uncancel()
 self._parent_task.cancel()
-# Exceptions are heavy objects that can have object
-# cycles (bad for GC); let's not keep a reference to
-# a bunch of them.
 try:
-me = BaseExceptionGroup('unhandled errors in a TaskGroup', 
self._errors)
-raise me from None
+raise BaseExceptionGroup(
+'unhandled errors in a TaskGroup',
+self._errors,
+) from None
 finally:
-self._errors = None
+exc = None
+
 
 def create_task(self, coro, *, name=None, context=None):
 """Create a new task in this group and return it.
diff --git a/Lib/test/test_asyncio/test_futures.py 
b/Lib/test/test_asyncio/test_futures.py
index 458b70451a306a..c566b28adb2408 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -659,6 +659,28 @@ def __del__(self):
 fut = self._new_future(loop=self.loop)
 fut.set_result(Evil())
 
+def test_future_cancelled_result_refcycles(self):
+f = self._new_future(loop=self.loop)
+f.cancel()
+exc = None
+try:
+f.result()
+except asyncio.CancelledError as e:
+exc = e
+

[Python-checkins] gh-125461: Remove Python 2 from identifiers in doc (GH-125462)

2024-10-14 Thread willingc
https://github.com/python/cpython/commit/5dac0dceda9097d46a0b5a6ad7c927e002c6c7a5
commit: 5dac0dceda9097d46a0b5a6ad7c927e002c6c7a5
branch: main
author: Paul Hoffman 
committer: willingc 
date: 2024-10-14T15:26:57Z
summary:

gh-125461: Remove Python 2 from identifiers in doc (GH-125462)

Remove Python 2 from identifiers in doc

files:
M Doc/reference/lexical_analysis.rst

diff --git a/Doc/reference/lexical_analysis.rst 
b/Doc/reference/lexical_analysis.rst
index ae5408ee386bbd..f7167032ad7df9 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -284,11 +284,10 @@ UAX-31, with elaboration and changes as defined below; 
see also :pep:`3131` for
 further details.
 
 Within the ASCII range (U+0001..U+007F), the valid characters for identifiers
-are the same as in Python 2.x: the uppercase and lowercase letters ``A`` 
through
+include the uppercase and lowercase letters ``A`` through
 ``Z``, the underscore ``_`` and, except for the first character, the digits
 ``0`` through ``9``.
-
-Python 3.0 introduces additional characters from outside the ASCII range (see
+Python 3.0 introduced additional characters from outside the ASCII range (see
 :pep:`3131`).  For these characters, the classification uses the version of the
 Unicode Character Database as included in the :mod:`unicodedata` module.
 

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