[Python-checkins] gh-125522 : add explicit exception types to bare excepts in tests (#125523)
https://github.com/python/cpython/commit/e97910cdb76c1f1dadfc4721b828611e4f4b6449 commit: e97910cdb76c1f1dadfc4721b828611e4f4b6449 branch: main author: Irit Katriel <[email protected]> committer: iritkatriel <[email protected]> date: 2024-10-15T17:00:04+01:00 summary: gh-125522 : add explicit exception types to bare excepts in tests (#125523) files: M Lib/test/test_cmd_line_script.py M Lib/test/test_coroutines.py M Lib/test/test_file.py M Lib/test/test_listcomps.py M Lib/test/test_logging.py M Lib/test/test_pdb.py M Lib/test/test_peepholer.py M Lib/test/test_raise.py M Lib/test/test_sys_setprofile.py M Lib/test/test_unittest/test_result.py M Lib/test/test_with.py diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 3a5a8abf81e43d..f30107225ff612 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -543,7 +543,7 @@ def test_pep_409_verbiage(self): script = textwrap.dedent("""\ try: raise ValueError -except: +except ValueError: raise NameError from None """) with os_helper.temp_dir() as script_dir: diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index a677301c62becc..e6d65e7d90abb1 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1185,7 +1185,7 @@ async def f(): async def g(): try: raise KeyError -except: +except KeyError: return await f() _, result = run_async(g()) diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index 9df55278693531..1206032a93566e 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -126,7 +126,7 @@ def testMethods(self): # it must also return None if an exception was given try: 1/0 -except: +except ZeroDivisionError: self.assertEqual(self.f.__exit__(*sys.exc_info()), None) def testReadWhenWriting(self): diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index 45644d6c092782..cffdeeacc5d73b 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -609,7 +609,7 @@ def test_comp_in_try_except(self): result = snapshot = None try: result = [{func}(value) for value in value] -except: +except ValueError: snapshot = value raise """ @@ -643,7 +643,7 @@ def test_exception_in_post_comp_call(self): value = [1, None] try: [v for v in value].sort() -except: +except TypeError: pass """ self._check_in_scopes(code, {"value": [1, None]}) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index d4ceb7c8dc0b41..e72f222e1c7eeb 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4877,7 +4877,7 @@ def test_formatting(self): r.addHandler(h) try: raise RuntimeError('deliberate mistake') -except: +except RuntimeError: logging.exception('failed', stack_info=True) r.removeHandler(h) h.close() diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 474d31f1ae03d9..084b7cd4cad219 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1081,7 +1081,7 @@ def test_convenience_variables(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... try: ... raise Exception('test') -... except: +... except Exception: ... pass ... return 1 @@ -1153,7 +1153,7 @@ def test_convenience_variables(): Exception('test') (Pdb) next > (5)util_function() --> except: +-> except Exception: (Pdb) $_exception *** KeyError: '_exception' (Pdb) return diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index dd3eaeb39e7fe3..b143f3d27a1537 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -766,7 +766,7 @@ def test_load_fast_unknown_after_error_2(self): def f(): try: 1 / 0 -except: +except ZeroDivisionError: print(a, b, c, d, e, f, g) a = b = c = d = e = f = g = 1 self.assertInBytecode(f, 'LOAD_FAST_CHECK') diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index 6d26a61bee4292..dcf0753bc828f3 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -48,7 +48,7 @@ def test_except_reraise(self): def reraise(): try: raise TypeError("foo") -except: +except TypeError: try: raise KeyError("caught") except KeyError: @@ -60,7 +60,7
[Python-checkins] [3.12] gh-89819: Add argument_default and conflict_handler to add_argument_group() docs (GH-125379) (GH-125539)
https://github.com/python/cpython/commit/1cab726622985a5596529521f471aea8588747c3 commit: 1cab726622985a5596529521f471aea8588747c3 branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: serhiy-storchaka date: 2024-10-15T16:09:55Z summary: [3.12] gh-89819: Add argument_default and conflict_handler to add_argument_group() docs (GH-125379) (GH-125539) (cherry picked from commit c9826c11db25e81b1a90c837f84074879f1b1126) Co-authored-by: Savannah Ostrowski files: M Doc/library/argparse.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index a1f08ea272934f..87d9a45539a1dd 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1740,7 +1740,8 @@ FileType objects Argument groups ^^^ -.. method:: ArgumentParser.add_argument_group(title=None, description=None) +.. method:: ArgumentParser.add_argument_group(title=None, description=None, *, \ + [argument_default], [conflict_handler]) By default, :class:`ArgumentParser` groups command-line arguments into "positional arguments" and "options" when displaying help @@ -1785,6 +1786,11 @@ Argument groups --bar BAR bar help + The optional, keyword-only parameters argument_default_ and conflict_handler_ + allow for finer-grained control of the behavior of the argument group. These + parameters have the same meaning as in the :class:`ArgumentParser` constructor, + but apply specifically to the argument group rather than the entire parser. + Note that any arguments not in your user-defined groups will end up back in the usual "positional arguments" and "optional arguments" sections. ___ 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-124375: Avoid calling `_PyMem_ProcessDelayed` on other thread states (#124459)
https://github.com/python/cpython/commit/54c6fcbefd33a8d8bf8c004cf1aad3be3d37b933
commit: 54c6fcbefd33a8d8bf8c004cf1aad3be3d37b933
branch: main
author: Sam Gross
committer: colesbury
date: 2024-10-15T16:09:35Z
summary:
gh-124375: Avoid calling `_PyMem_ProcessDelayed` on other thread states
(#124459)
This fixes a crash when running the PyO3 test suite on the free-threaded
build. The `qsbr` field is initialized after the `PyThreadState` is
added to the interpreter's linked list -- it might still be NULL.
Instead, we "steal" the queue of to-be-freed memory blocks. This is
always initialized (possibly empty) and protected by the stop the world
pause.
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst
M Python/gc_free_threading.c
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst
new file mode 100644
index 00..4bd17a6e683bc7
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst
@@ -0,0 +1 @@
+Fix a crash in the free threading build when the GC runs concurrently with a
new thread starting.
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 38564d9d9b0058..3814cd46e2b440 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -420,18 +420,24 @@ merge_queued_objects(_PyThreadStateImpl *tstate, struct
collection_state *state)
static void
process_delayed_frees(PyInterpreterState *interp)
{
-// In STW status, we can observe the latest write sequence by
-// advancing the write sequence immediately.
+// While we are in a "stop the world" pause, we can observe the latest
+// write sequence by advancing the write sequence immediately.
_Py_qsbr_advance(&interp->qsbr);
_PyThreadStateImpl *current_tstate = (_PyThreadStateImpl
*)_PyThreadState_GET();
_Py_qsbr_quiescent_state(current_tstate->qsbr);
+
+// Merge the queues from other threads into our own queue so that we can
+// process all of the pending delayed free requests at once.
HEAD_LOCK(&_PyRuntime);
-PyThreadState *tstate = interp->threads.head;
-while (tstate != NULL) {
-_PyMem_ProcessDelayed(tstate);
-tstate = (PyThreadState *)tstate->next;
+for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
+_PyThreadStateImpl *other = (_PyThreadStateImpl *)p;
+if (other != current_tstate) {
+llist_concat(¤t_tstate->mem_free_queue,
&other->mem_free_queue);
+}
}
HEAD_UNLOCK(&_PyRuntime);
+
+_PyMem_ProcessDelayed((PyThreadState *)current_tstate);
}
// Subtract an incoming reference from the computed "gc_refs" refcount.
___
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-89819: Add argument_default and conflict_handler to add_argument_group() docs (GH-125379) (GH-125538)
https://github.com/python/cpython/commit/cc66dfc86ca779550fb3a137d9ed9109a5247f95 commit: cc66dfc86ca779550fb3a137d9ed9109a5247f95 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: serhiy-storchaka date: 2024-10-15T16:09:50Z summary: [3.13] gh-89819: Add argument_default and conflict_handler to add_argument_group() docs (GH-125379) (GH-125538) (cherry picked from commit c9826c11db25e81b1a90c837f84074879f1b1126) Co-authored-by: Savannah Ostrowski files: M Doc/library/argparse.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 4e66611ab172d1..607364791bc8c1 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1785,7 +1785,8 @@ FileType objects Argument groups ^^^ -.. method:: ArgumentParser.add_argument_group(title=None, description=None) +.. method:: ArgumentParser.add_argument_group(title=None, description=None, *, \ + [argument_default], [conflict_handler]) By default, :class:`ArgumentParser` groups command-line arguments into "positional arguments" and "options" when displaying help @@ -1830,6 +1831,11 @@ Argument groups --bar BAR bar help + The optional, keyword-only parameters argument_default_ and conflict_handler_ + allow for finer-grained control of the behavior of the argument group. These + parameters have the same meaning as in the :class:`ArgumentParser` constructor, + but apply specifically to the argument group rather than the entire parser. + Note that any arguments not in your user-defined groups will end up back in the usual "positional arguments" and "optional arguments" sections. ___ 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-125206: Bug in ctypes with old libffi is fixed (#125322)
https://github.com/python/cpython/commit/aac89b54c5ee03c4d64fbdfbb6ea3001e26aa83a
commit: aac89b54c5ee03c4d64fbdfbb6ea3001e26aa83a
branch: main
author: Mikhail Efimov
committer: vstinner
date: 2024-10-15T16:17:10Z
summary:
gh-125206: Bug in ctypes with old libffi is fixed (#125322)
Workaround for old libffi versions is added.
Module ctypes now supports C11 double complex only with libffi >= 3.3.0.
Co-authored-by: Sergey B Kirpichev
files:
A Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst
M Lib/test/test_ctypes/test_libc.py
M Modules/_ctypes/_ctypes.c
M Modules/_ctypes/_ctypes_test.c
M Modules/_ctypes/callproc.c
M Modules/_ctypes/cfield.c
M Modules/_ctypes/ctypes.h
M configure
M configure.ac
M pyconfig.h.in
diff --git a/Lib/test/test_ctypes/test_libc.py
b/Lib/test/test_ctypes/test_libc.py
index cab3cc9f46003a..df7dbc0ae264a0 100644
--- a/Lib/test/test_ctypes/test_libc.py
+++ b/Lib/test/test_ctypes/test_libc.py
@@ -23,7 +23,7 @@ def test_sqrt(self):
self.assertEqual(lib.my_sqrt(2.0), math.sqrt(2.0))
@unittest.skipUnless(hasattr(ctypes, "c_double_complex"),
- "requires C11 complex type")
+ "requires C11 complex type and libffi >= 3.3.0")
def test_csqrt(self):
lib.my_csqrt.argtypes = ctypes.c_double_complex,
lib.my_csqrt.restype = ctypes.c_double_complex
diff --git
a/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst
b/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst
new file mode 100644
index 00..ef7975ebcb376b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-11-18-03-05.gh-issue-125206.pWRRK6.rst
@@ -0,0 +1,2 @@
+Workaround for old libffi versions is added. Module ctypes supports
+:c:expr:`double complex` only with libffi >= 3.3.0. Patch by Mikhail Efimov.
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 8435ee4090b9e5..d6a5b75a03d3fe 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -1747,7 +1747,7 @@ class _ctypes.c_void_p "PyObject *"
"clinic_state_sub()->PyCSimpleType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd4d9646c56f43a9]*/
-#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE)
+#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdCEFfuzZqQPXOv?g";
#else
static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g";
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c
index 5142bb81cf685c..7bac592fd38fb9 100644
--- a/Modules/_ctypes/_ctypes_test.c
+++ b/Modules/_ctypes/_ctypes_test.c
@@ -13,9 +13,7 @@
#include
-#include // FFI_TARGET_HAS_COMPLEX_TYPE
-
-#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE)
+#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
# include "../_complex.h"// csqrt()
# undef I// for _ctypes_test_generated.c.h
#endif
@@ -449,7 +447,7 @@ EXPORT(double) my_sqrt(double a)
return sqrt(a);
}
-#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE)
+#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
EXPORT(double complex) my_csqrt(double complex a)
{
return csqrt(a);
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index fd89d9c67b3fc0..5ac9cf16681645 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -105,7 +105,7 @@ module _ctypes
#include "pycore_global_objects.h"// _Py_ID()
#include "pycore_traceback.h" // _PyTraceback_Add()
-#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE)
+#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
#include "../_complex.h" // complex
#endif
@@ -655,7 +655,7 @@ union result {
double d;
float f;
void *p;
-#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE)
+#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
double complex C;
float complex E;
long double complex F;
diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
index 53a946e750b866..3220852c8398e0 100644
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
@@ -14,7 +14,7 @@
#include
#include "ctypes.h"
-#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE)
+#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
# include "../_complex.h"// complex
#endif
@@ -972,7 +972,7 @@ d_get(void *ptr, Py_ssize_t size)
return PyFloat_FromDouble(val);
}
-#if defined(Py_HAVE_C_COMPLEX) && defined(FFI_TARGET_HAS_COMPLEX_TYPE)
+#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
static PyObject *
C_set(void *ptr, PyObject *value, Py_ssize_t size)
{
@@ -1545,7 +1545,7 @@ static struct fielddesc formattable[] = {
[Python-checkins] gh-125512: Revert "gh-124872: Replace enter/exit events with "switched" (#124776)" (#125513)
https://github.com/python/cpython/commit/d3c82b9ccedd77fc302f5ab8ab0220b3372f574c commit: d3c82b9ccedd77fc302f5ab8ab0220b3372f574c branch: main author: Kirill Podoprigora committer: hugovk <[email protected]> date: 2024-10-15T17:42:16+03:00 summary: gh-125512: Revert "gh-124872: Replace enter/exit events with "switched" (#124776)" (#125513) 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 b7c6550ff34aac..8eba54a80dc80d 100644 --- a/Doc/c-api/contextvars.rst +++ b/Doc/c-api/contextvars.rst @@ -123,10 +123,16 @@ Context object management functions: Enumeration of possible context object watcher events: - - ``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. + - ``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. .. versionadded:: 3.14 diff --git a/Include/cpython/context.h b/Include/cpython/context.h index 3a7a4b459c09ad..3c9be7873b9399 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -29,11 +29,20 @@ PyAPI_FUNC(int) PyContext_Exit(PyObject *); typedef enum { /* - * 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. + * 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. */ -Py_CONTEXT_SWITCHED = 1, +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, } PyContextEvent; /* diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index 4680d6765de122..f21d2627c6094b 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -577,62 +577,68 @@ class TestContextObjectWatchers(unittest.TestCase): def context_watcher(self, which_watcher): wid = _testcapi.add_context_watcher(which_watcher) try: -switches = _testcapi.get_context_switches(which_watcher) -except ValueError: -switches = None -try: -yield switches +yield wid finally: _testcapi.clear_context_watcher(wid) -def assert_event_counts(self, want_0, want_1): -self.assertEqual(len(_testcapi.get_context_switches(0)), want_0) -self.assertEqual(len(_testcapi.get_context_switches(1)), want_1) +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)) +self.assertEqual( +exp_exit_0, _testcapi.get_context_watcher_num_exit_events(0)) +self.assertEqual( +exp_enter_1, _testcapi.get_context_watcher_num_enter_events(1)) +self.assertEqual( +exp_exit_1, _testcapi.get_context_watcher_num_exit_events(1)) def test_context_object_events_dispatched(self): # verify that all counts are zero before any watchers are registered -self.assert_event_counts(0, 0) +self.assert_event_counts(0, 0, 0, 0) # verify that all counts remain zero when a context object is # entered and exited with no watchers registered ctx = contextvars.copy_context() -ctx.run(self.assert_event_counts, 0, 0) -self.assert_event_counts(0, 0) +ctx.run(self.assert_event_counts, 0, 0, 0, 0) +
[Python-checkins] gh-119786: fix typo in compiler.md (#125456)
https://github.com/python/cpython/commit/b903fc38d8ec74f61fb5ca8a3f5fd025915bceac commit: b903fc38d8ec74f61fb5ca8a3f5fd025915bceac branch: main author: Mikhail Efimov committer: iritkatriel <[email protected]> date: 2024-10-15T16:38:19+01:00 summary: gh-119786: fix typo in compiler.md (#125456) files: M InternalDocs/compiler.md diff --git a/InternalDocs/compiler.md b/InternalDocs/compiler.md index f27e73b274511f..acef6def563154 100644 --- a/InternalDocs/compiler.md +++ b/InternalDocs/compiler.md @@ -515,7 +515,7 @@ Important files Creates C structs corresponding to the ASDL types. Also contains code for marshalling AST nodes (core ASDL types have marshalling code in [Python/asdl.c](https://github.com/python/cpython/blob/main/Python/asdl.c)). -"File automatically generated by +File automatically generated by [Parser/asdl_c.py](https://github.com/python/cpython/blob/main/Parser/asdl_c.py). This file must be committed separately after every grammar change is committed since the ``__version__`` value is set to the latest @@ -572,7 +572,7 @@ Important files * [Include/internal/pycore_ast.h](https://github.com/python/cpython/blob/main/Include/internal/pycore_ast.h) : Contains the actual definitions of the C structs as generated by [Python/Python-ast.c](https://github.com/python/cpython/blob/main/Python/Python-ast.c) -"Automatically generated by +Automatically generated by [Parser/asdl_c.py](https://github.com/python/cpython/blob/main/Parser/asdl_c.py). * [Include/internal/pycore_asdl.h](https://github.com/python/cpython/blob/main/Include/internal/pycore_asdl.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-125451: Skip concurrent.futures test_processes_terminate() (#125533)
https://github.com/python/cpython/commit/c6e8ff86b2bf8cf597622d416f8befae940366fa commit: c6e8ff86b2bf8cf597622d416f8befae940366fa branch: main author: Victor Stinner committer: vstinner date: 2024-10-15T15:42:55Z summary: gh-125451: Skip concurrent.futures test_processes_terminate() (#125533) The test hangs randomly. It tries to serialize local lock and a local function which are not possible. files: M Lib/test/test_concurrent_futures/test_shutdown.py diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py index 7a4065afd46fc8..ba3618614a9bf9 100644 --- a/Lib/test/test_concurrent_futures/test_shutdown.py +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -253,6 +253,9 @@ def test_cancel_futures_wait_false(self): class ProcessPoolShutdownTest(ExecutorShutdownTest): +# gh-125451: 'lock' cannot be serialized, the test is broken +# and hangs randomly [email protected](True, "broken test") def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() ___ 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-100141: Allow pdb to deal with empty file (#125425)
https://github.com/python/cpython/commit/bb9604b62ae7f043594ffea9287f9213067cc7fb
commit: bb9604b62ae7f043594ffea9287f9213067cc7fb
branch: main
author: Tian Gao
committer: gaogaotiantian
date: 2024-10-15T11:45:23-04:00
summary:
gh-100141: Allow pdb to deal with empty file (#125425)
files:
A Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst
M Lib/pdb.py
M Lib/test/test_pdb.py
diff --git a/Lib/pdb.py b/Lib/pdb.py
index d9aed24bfcd8e7..2b36b1e3fa7cbe 100644
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -429,8 +429,7 @@ def user_call(self, frame, argument_list):
def user_line(self, frame):
"""This function is called when we stop or break at this line."""
if self._wait_for_mainpyfile:
-if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
-or frame.f_lineno <= 0):
+if (self.mainpyfile != self.canonic(frame.f_code.co_filename)):
return
self._wait_for_mainpyfile = False
self.bp_commands(frame)
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 3dc65fdfc03409..474d31f1ae03d9 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -3999,6 +3999,16 @@ def _create_fake_frozen_module():
# verify that pdb found the source of the "frozen" function
self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel
statement not found")
+def test_empty_file(self):
+script = ''
+commands = 'q\n'
+# We check that pdb stopped at line 0, but anything reasonable
+# is acceptable here, as long as it does not halt
+stdout, _ = self.run_pdb_script(script, commands)
+self.assertIn('main.py(0)', stdout)
+stdout, _ = self.run_pdb_module(script, commands)
+self.assertIn('__main__.py(0)', stdout)
+
def test_non_utf8_encoding(self):
script_dir = os.path.join(os.path.dirname(__file__), 'encoded_modules')
for filename in os.listdir(script_dir):
diff --git
a/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst
b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst
new file mode 100644
index 00..c366b0ad4040d3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst
@@ -0,0 +1 @@
+Fixed the bug where :mod:`pdb` will be stuck in an infinite loop when
debugging an empty file.
___
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-89819: Add argument_default and conflict_handler to add_argument_group() docs (GH-125379)
https://github.com/python/cpython/commit/c9826c11db25e81b1a90c837f84074879f1b1126 commit: c9826c11db25e81b1a90c837f84074879f1b1126 branch: main author: Savannah Ostrowski committer: serhiy-storchaka date: 2024-10-15T15:48:28Z summary: gh-89819: Add argument_default and conflict_handler to add_argument_group() docs (GH-125379) files: M Doc/library/argparse.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index d58c75eef3e739..51ab8e29ff96d5 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1808,7 +1808,8 @@ FileType objects Argument groups ^^^ -.. method:: ArgumentParser.add_argument_group(title=None, description=None) +.. method:: ArgumentParser.add_argument_group(title=None, description=None, *, \ + [argument_default], [conflict_handler]) By default, :class:`ArgumentParser` groups command-line arguments into "positional arguments" and "options" when displaying help @@ -1853,6 +1854,11 @@ Argument groups --bar BAR bar help + The optional, keyword-only parameters argument_default_ and conflict_handler_ + allow for finer-grained control of the behavior of the argument group. These + parameters have the same meaning as in the :class:`ArgumentParser` constructor, + but apply specifically to the argument group rather than the entire parser. + Note that any arguments not in your user-defined groups will end up back in the usual "positional arguments" and "optional arguments" sections. ___ 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-92953: Improve nextpool/prevpool comment. (gh-125545)
https://github.com/python/cpython/commit/206de4155b01f6285c5551d2224391fa1fa0ac14
commit: 206de4155b01f6285c5551d2224391fa1fa0ac14
branch: main
author: Neil Schemenauer
committer: nascheme
date: 2024-10-15T11:47:20-07:00
summary:
gh-92953: Improve nextpool/prevpool comment. (gh-125545)
The meaning of these links depends on which list the pool is part of.
They are only the same size class if on the "usedpools" list.
files:
M Include/internal/pycore_obmalloc.h
diff --git a/Include/internal/pycore_obmalloc.h
b/Include/internal/pycore_obmalloc.h
index 9140d8f08f0af1..a7ba8f340737aa 100644
--- a/Include/internal/pycore_obmalloc.h
+++ b/Include/internal/pycore_obmalloc.h
@@ -255,8 +255,8 @@ struct pool_header {
union { pymem_block *_padding;
uint count; } ref; /* number of allocated blocks*/
pymem_block *freeblock; /* pool's free list head */
-struct pool_header *nextpool; /* next pool of this size class */
-struct pool_header *prevpool; /* previous pool ""*/
+struct pool_header *nextpool; /* see "Pool table" for meaning */
+struct pool_header *prevpool; /* " */
uint arenaindex;/* index into arenas of base adr */
uint szidx; /* block size class index*/
uint nextoffset;/* bytes to virgin block */
___
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-124218: Use per-thread refcounts for code objects (#125216)
https://github.com/python/cpython/commit/3ea488aac44887a7cdb30be69580c81a0ca6afe2
commit: 3ea488aac44887a7cdb30be69580c81a0ca6afe2
branch: main
author: Sam Gross
committer: colesbury
date: 2024-10-15T15:06:41-04:00
summary:
gh-124218: Use per-thread refcounts for code objects (#125216)
Use per-thread refcounting for the reference from function objects to
their corresponding code object. This can be a source of contention when
frequently creating nested functions. Deferred refcounting alone isn't a
great fit here because these references are on the heap and may be
modified by other libraries.
files:
M Include/cpython/code.h
M Include/cpython/object.h
M Include/internal/pycore_object.h
M Include/internal/pycore_uniqueid.h
M Objects/codeobject.c
M Objects/funcobject.c
M Objects/typeobject.c
M Python/gc_free_threading.c
M Python/pylifecycle.c
M Python/pystate.c
M Python/uniqueid.c
diff --git a/Include/cpython/code.h b/Include/cpython/code.h
index 03622698113ee7..af9149b9c38e62 100644
--- a/Include/cpython/code.h
+++ b/Include/cpython/code.h
@@ -132,6 +132,7 @@ typedef struct {
_PyCoCached *_co_cached; /* cached co_* attributes */
\
uintptr_t _co_instrumentation_version; /* current instrumentation version
*/ \
_PyCoMonitoringData *_co_monitoring; /* Monitoring data */
\
+Py_ssize_t _co_unique_id; /* ID used for per-thread refcounting */ \
int _co_firsttraceable; /* index of first traceable instruction */
\
/* Scratch space for extra data relating to the code object.
\
Type is a void* to keep the format private in codeobject.c to force
\
diff --git a/Include/cpython/object.h b/Include/cpython/object.h
index 9d092749b90096..f0f61796cd3ec8 100644
--- a/Include/cpython/object.h
+++ b/Include/cpython/object.h
@@ -272,7 +272,7 @@ typedef struct _heaptypeobject {
void *ht_token; // Storage for the "Py_tp_token" slot
struct _specialization_cache _spec_cache; // For use by the specializer.
#ifdef Py_GIL_DISABLED
-Py_ssize_t unique_id; // ID used for thread-local refcounting
+Py_ssize_t unique_id; // ID used for per-thread refcounting
#endif
/* here are optional user slots, followed by the members. */
} PyHeapTypeObject;
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index 8832692d03c29e..ad1a7d7e120519 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -14,7 +14,7 @@ extern "C" {
#include "pycore_interp.h"// PyInterpreterState.gc
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED
#include "pycore_pystate.h" // _PyInterpreterState_GET()
-#include "pycore_uniqueid.h" // _PyType_IncrefSlow
+#include "pycore_uniqueid.h" // _PyObject_ThreadIncrefSlow()
// This value is added to `ob_ref_shared` for objects that use deferred
// reference counting so that they are not immediately deallocated when the
@@ -291,7 +291,31 @@ extern bool _PyRefchain_IsTraced(PyInterpreterState
*interp, PyObject *obj);
#ifndef Py_GIL_DISABLED
# define _Py_INCREF_TYPE Py_INCREF
# define _Py_DECREF_TYPE Py_DECREF
+# define _Py_INCREF_CODE Py_INCREF
+# define _Py_DECREF_CODE Py_DECREF
#else
+static inline void
+_Py_THREAD_INCREF_OBJECT(PyObject *obj, Py_ssize_t unique_id)
+{
+_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
+
+// Unsigned comparison so that `unique_id=-1`, which indicates that
+// per-thread refcounting has been disabled on this object, is handled by
+// the "else".
+if ((size_t)unique_id < (size_t)tstate->refcounts.size) {
+# ifdef Py_REF_DEBUG
+_Py_INCREF_IncRefTotal();
+# endif
+_Py_INCREF_STAT_INC();
+tstate->refcounts.values[unique_id]++;
+}
+else {
+// The slow path resizes the per-thread refcount array if necessary.
+// It handles the unique_id=-1 case to keep the inlinable function
smaller.
+_PyObject_ThreadIncrefSlow(obj, unique_id);
+}
+}
+
static inline void
_Py_INCREF_TYPE(PyTypeObject *type)
{
@@ -308,29 +332,38 @@ _Py_INCREF_TYPE(PyTypeObject *type)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Warray-bounds"
#endif
+_Py_THREAD_INCREF_OBJECT((PyObject *)type, ((PyHeapTypeObject
*)type)->unique_id);
+#if defined(__GNUC__) && __GNUC__ >= 11
+# pragma GCC diagnostic pop
+#endif
+}
+
+static inline void
+_Py_INCREF_CODE(PyCodeObject *co)
+{
+_Py_THREAD_INCREF_OBJECT((PyObject *)co, co->_co_unique_id);
+}
+static inline void
+_Py_THREAD_DECREF_OBJECT(PyObject *obj, Py_ssize_t unique_id)
+{
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
-PyHeapTypeObject *ht = (PyHeapTypeObject *)type;
// Unsigned comparison so that `unique_id=-1`, which indicates that
-// per-thread refcounting has been disabled on this type, is handled by
+// per-thread refcounting has been disa
[Python-checkins] gh-125234: Make PyInitConfig_Free(NULL) a no-op (#125266)
https://github.com/python/cpython/commit/546dddca43a2a69dbe33d230e9e540636b403270
commit: 546dddca43a2a69dbe33d230e9e540636b403270
branch: main
author: RUANG (Roy James)
committer: erlend-aasland
date: 2024-10-15T09:21:16Z
summary:
gh-125234: Make PyInitConfig_Free(NULL) a no-op (#125266)
files:
M Doc/c-api/init_config.rst
M Programs/_testembed.c
M Python/initconfig.c
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index 6f8962afc7af0d..66e845df2e6aa5 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -1621,6 +1621,8 @@ Create Config
Free memory of the initialization configuration *config*.
+ If *config* is ``NULL``, no operation is performed.
+
Error Handling
--
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index ab619e32429d63..0fb45b2265e3c6 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -1896,6 +1896,7 @@ static int test_initconfig_api(void)
goto error;
}
PyInitConfig_Free(config);
+PyInitConfig_Free(NULL);
dump_config();
Py_Finalize();
diff --git a/Python/initconfig.c b/Python/initconfig.c
index 58ac5e7d7eaeff..c142438b02bfd9 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -3457,6 +3457,9 @@ PyInitConfig_Create(void)
void
PyInitConfig_Free(PyInitConfig *config)
{
+if (config == NULL) {
+return;
+}
free(config->err_msg);
free(config);
}
___
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-125517: Fix unreachable code warnings in `_testembed.c` (#125518)
https://github.com/python/cpython/commit/c8a1818fb01937b66b93728c11d68c9f9af688a5
commit: c8a1818fb01937b66b93728c11d68c9f9af688a5
branch: main
author: sobolevn
committer: sobolevn
date: 2024-10-15T13:12:32Z
summary:
gh-125517: Fix unreachable code warnings in `_testembed.c` (#125518)
files:
M Doc/c-api/init_config.rst
M Programs/_testembed.c
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index 66e845df2e6aa5..6194d7446c73e4 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -1825,14 +1825,18 @@ return ``-1`` on error:
PyInitConfig_Free(config);
return 0;
-// Display the error message
-const char *err_msg;
error:
-(void)PyInitConfig_GetError(config, &err_msg);
-printf("PYTHON INIT ERROR: %s\n", err_msg);
-PyInitConfig_Free(config);
+{
+// Display the error message
+// This uncommon braces style is used, because you cannot make
+// goto targets point to variable declarations.
+const char *err_msg;
+(void)PyInitConfig_GetError(config, &err_msg);
+printf("PYTHON INIT ERROR: %s\n", err_msg);
+PyInitConfig_Free(config);
-return -1;
+return -1;
+}
}
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 0fb45b2265e3c6..d15dd519dbf6af 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -1902,11 +1902,13 @@ static int test_initconfig_api(void)
Py_Finalize();
return 0;
-const char *err_msg;
error:
-(void)PyInitConfig_GetError(config, &err_msg);
-printf("Python init failed: %s\n", err_msg);
-exit(1);
+{
+const char *err_msg;
+(void)PyInitConfig_GetError(config, &err_msg);
+printf("Python init failed: %s\n", err_msg);
+exit(1);
+}
}
@@ -2050,11 +2052,13 @@ static int test_initconfig_module(void)
Py_Finalize();
return 0;
-const char *err_msg;
error:
-(void)PyInitConfig_GetError(config, &err_msg);
-printf("Python init failed: %s\n", err_msg);
-exit(1);
+{
+const char *err_msg;
+(void)PyInitConfig_GetError(config, &err_msg);
+printf("Python init failed: %s\n", err_msg);
+exit(1);
+}
}
___
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-125269: Use `AC_LINK_IF_ELSE` to detect if `-latomic` is needed (GH-125416) (#125493)
https://github.com/python/cpython/commit/8cf646adeab0e5a368cc2875068a725a324fc7c1 commit: 8cf646adeab0e5a368cc2875068a725a324fc7c1 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: vstinner date: 2024-10-15T11:29:03+02:00 summary: [3.13] gh-125269: Use `AC_LINK_IF_ELSE` to detect if `-latomic` is needed (GH-125416) (#125493) gh-125269: Use `AC_LINK_IF_ELSE` to detect if `-latomic` is needed (GH-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. (cherry picked from commit 8d42e2d915c3096e7eac1c649751d1da567bb7c3) Co-authored-by: Sam Gross 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 e1bfd73f24be96..82089e6256f75b 100755 --- a/configure +++ b/configure @@ -28618,10 +28618,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. */ @@ -28663,16 +28659,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 cfe9de0f7f3819..13dc9fa36de887 100644 --- a/configure.ac +++ b/configure.ac @@ -7397,7 +7397,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 @@ -7434,9 +7434,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-125041: test_zlib: For s390x HW acceleration, only skip checking the compressed bytes (#125042)
https://github.com/python/cpython/commit/cc5a225cdc2a5d4e035dd08d59cef39182c10a6c
commit: cc5a225cdc2a5d4e035dd08d59cef39182c10a6c
branch: main
author: Petr Viktorin
committer: encukou
date: 2024-10-15T11:29:43Z
summary:
gh-125041: test_zlib: For s390x HW acceleration, only skip checking the
compressed bytes (#125042)
files:
A Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst
M Lib/test/support/__init__.py
M Lib/test/test_zlib.py
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index d768bead7120c7..f05be2b6bdf496 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -2625,9 +2625,9 @@ def exceeds_recursion_limit():
return get_c_recursion_limit() * 3
-#Windows doesn't have os.uname() but it doesn't support s390x.
-skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine ==
's390x',
-'skipped on s390x')
+# Windows doesn't have os.uname() but it doesn't support s390x.
+is_s390x = hasattr(os, 'uname') and os.uname().machine == 's390x'
+skip_on_s390x = unittest.skipIf(is_s390x, 'skipped on s390x')
Py_TRACE_REFS = hasattr(sys, 'getobjects')
diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py
index ef02c64f886f8a..8b4bb8750f8f5c 100644
--- a/Lib/test/test_zlib.py
+++ b/Lib/test/test_zlib.py
@@ -6,7 +6,7 @@
import pickle
import random
import sys
-from test.support import bigmemtest, _1G, _4G, skip_on_s390x
+from test.support import bigmemtest, _1G, _4G, is_s390x
zlib = import_helper.import_module('zlib')
@@ -33,8 +33,9 @@ def
_zlib_runtime_version_tuple(zlib_version=zlib.ZLIB_RUNTIME_VERSION):
ZLIB_RUNTIME_VERSION_TUPLE = _zlib_runtime_version_tuple()
-# bpo-46623: On s390x, when a hardware accelerator is used, using different
-# ways to compress data with zlib can produce different compressed data.
+# bpo-46623: When a hardware accelerator is used (currently only on s390x),
+# using different ways to compress data with zlib can produce different
+# compressed data.
# Simplified test_pair() code:
#
# def func1(data):
@@ -57,8 +58,10 @@ def
_zlib_runtime_version_tuple(zlib_version=zlib.ZLIB_RUNTIME_VERSION):
#
# zlib.decompress(func1(data)) == zlib.decompress(func2(data)) == data
#
-# Make the assumption that s390x always has an accelerator to simplify the skip
-# condition.
+# To simplify the skip condition, make the assumption that s390x always has an
+# accelerator, and nothing else has it.
+HW_ACCELERATED = is_s390x
+
class VersionTestCase(unittest.TestCase):
@@ -223,12 +226,14 @@ def test_keywords(self):
bufsize=zlib.DEF_BUF_SIZE),
HAMLET_SCENE)
-@skip_on_s390x
def test_speech128(self):
# compress more data
data = HAMLET_SCENE * 128
x = zlib.compress(data)
-self.assertEqual(zlib.compress(bytearray(data)), x)
+# With hardware acceleration, the compressed bytes
+# might not be identical.
+if not HW_ACCELERATED:
+self.assertEqual(zlib.compress(bytearray(data)), x)
for ob in x, bytearray(x):
self.assertEqual(zlib.decompress(ob), data)
@@ -275,7 +280,6 @@ def test_64bit_compress(self, size):
class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
# Test compression object
-@skip_on_s390x
def test_pair(self):
# straightforward compress/decompress objects
datasrc = HAMLET_SCENE * 128
@@ -286,7 +290,10 @@ def test_pair(self):
x1 = co.compress(data)
x2 = co.flush()
self.assertRaises(zlib.error, co.flush) # second flush should not
work
-self.assertEqual(x1 + x2, datazip)
+# With hardware acceleration, the compressed bytes might not
+# be identical.
+if not HW_ACCELERATED:
+self.assertEqual(x1 + x2, datazip)
for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
dco = zlib.decompressobj()
y1 = dco.decompress(v1 + v2)
diff --git
a/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst
b/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst
new file mode 100644
index 00..c7181eb9c1f3a9
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2024-10-07-14-13-38.gh-issue-125041.PKLWDf.rst
@@ -0,0 +1,3 @@
+Re-enable skipped tests for :mod:`zlib` on the s390x architecture: only skip
+checks of the compressed bytes, which can be different between zlib's
+software implementation and the hardware-accelerated implementation.
___
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-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (#125516)
https://github.com/python/cpython/commit/55c4f4c30b49734ce35dc88139b8b4fdc94c66fd commit: 55c4f4c30b49734ce35dc88139b8b4fdc94c66fd branch: main author: Irit Katriel <[email protected]> committer: iritkatriel <[email protected]> date: 2024-10-15T15:11:02+01:00 summary: gh-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (#125516) files: M Lib/test/test_traceback.py diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 455fea034198a6..77ef0c5b3c480d 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -150,7 +150,7 @@ def test_no_caret_with_no_debug_ranges_flag_python_traceback(self): import traceback try: x = 1 / 0 -except: +except ZeroDivisionError: traceback.print_exc() """) try: @@ -550,9 +550,10 @@ class PurePythonExceptionFormattingMixin: def get_exception(self, callable, slice_start=0, slice_end=-1): try: callable() -self.fail("No exception thrown.") -except: +except BaseException: return traceback.format_exc().splitlines()[slice_start:slice_end] +else: +self.fail("No exception thrown.") callable_line = get_exception.__code__.co_firstlineno + 2 @@ -2237,7 +2238,7 @@ def test_context_suppression(self): try: try: raise Exception -except: +except Exception: raise ZeroDivisionError from None except ZeroDivisionError as _: e = _ @@ -2589,9 +2590,9 @@ def exc(): try: try: raise EG("eg1", [ValueError(1), TypeError(2)]) -except: +except EG: raise EG("eg2", [ValueError(3), TypeError(4)]) -except: +except EG: raise ImportError(5) expected = ( @@ -2641,7 +2642,7 @@ def exc(): except Exception as e: exc = e raise EG("eg", [VE(1), exc, VE(4)]) -except: +except EG: raise EG("top", [VE(5)]) expected = (f' + Exception Group Traceback (most recent call last):\n' @@ -3454,7 +3455,7 @@ def test_long_context_chain(self): def f(): try: 1/0 -except: +except ZeroDivisionError: f() try: @@ -3558,7 +3559,7 @@ def test_comparison_params_variations(self): def raise_exc(): try: raise ValueError('bad value') -except: +except ValueError: raise def raise_with_locals(): ___ 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-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (GH-125516) (#125525)
https://github.com/python/cpython/commit/26725d1756424b8abff896ffed7b017dd59241fc commit: 26725d1756424b8abff896ffed7b017dd59241fc branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: iritkatriel <[email protected]> date: 2024-10-15T14:28:23Z summary: [3.12] gh-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (GH-125516) (#125525) gh-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (GH-125516) (cherry picked from commit 55c4f4c30b49734ce35dc88139b8b4fdc94c66fd) Co-authored-by: Irit Katriel <[email protected]> files: M Lib/test/test_traceback.py diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index d12b559cf076d6..119143e4f3a009 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -138,7 +138,7 @@ def test_no_caret_with_no_debug_ranges_flag_python_traceback(self): import traceback try: x = 1 / 0 -except: +except ZeroDivisionError: traceback.print_exc() """) try: @@ -386,9 +386,10 @@ class PurePythonExceptionFormattingMixin: def get_exception(self, callable, slice_start=0, slice_end=-1): try: callable() -self.fail("No exception thrown.") -except: +except BaseException: return traceback.format_exc().splitlines()[slice_start:slice_end] +else: +self.fail("No exception thrown.") callable_line = get_exception.__code__.co_firstlineno + 2 @@ -1490,7 +1491,7 @@ def test_context_suppression(self): try: try: raise Exception -except: +except Exception: raise ZeroDivisionError from None except ZeroDivisionError as _: e = _ @@ -1838,9 +1839,9 @@ def exc(): try: try: raise EG("eg1", [ValueError(1), TypeError(2)]) -except: +except EG: raise EG("eg2", [ValueError(3), TypeError(4)]) -except: +except EG: raise ImportError(5) expected = ( @@ -1889,7 +1890,7 @@ def exc(): except Exception as e: exc = e raise EG("eg", [VE(1), exc, VE(4)]) -except: +except EG: raise EG("top", [VE(5)]) expected = (f' + Exception Group Traceback (most recent call last):\n' @@ -2642,7 +2643,7 @@ def test_long_context_chain(self): def f(): try: 1/0 -except: +except ZeroDivisionError: f() try: @@ -2731,7 +2732,7 @@ def test_comparison_params_variations(self): def raise_exc(): try: raise ValueError('bad value') -except: +except ValueError: raise def raise_with_locals(): ___ 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-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (GH-125516) (#125524)
https://github.com/python/cpython/commit/3b8477b81a01d59f13d8068554405410eb590626 commit: 3b8477b81a01d59f13d8068554405410eb590626 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: iritkatriel <[email protected]> date: 2024-10-15T14:36:14Z summary: [3.13] gh-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (GH-125516) (#125524) gh-125514: fix bug in test_traceback utility. Specify exception types in except: clauses (GH-125516) (cherry picked from commit 55c4f4c30b49734ce35dc88139b8b4fdc94c66fd) Co-authored-by: Irit Katriel <[email protected]> files: M Lib/test/test_traceback.py diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index a78aded4ccf7ca..1365305971e56b 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -150,7 +150,7 @@ def test_no_caret_with_no_debug_ranges_flag_python_traceback(self): import traceback try: x = 1 / 0 -except: +except ZeroDivisionError: traceback.print_exc() """) try: @@ -550,9 +550,10 @@ class PurePythonExceptionFormattingMixin: def get_exception(self, callable, slice_start=0, slice_end=-1): try: callable() -self.fail("No exception thrown.") -except: +except BaseException: return traceback.format_exc().splitlines()[slice_start:slice_end] +else: +self.fail("No exception thrown.") callable_line = get_exception.__code__.co_firstlineno + 2 @@ -2234,7 +2235,7 @@ def test_context_suppression(self): try: try: raise Exception -except: +except Exception: raise ZeroDivisionError from None except ZeroDivisionError as _: e = _ @@ -2586,9 +2587,9 @@ def exc(): try: try: raise EG("eg1", [ValueError(1), TypeError(2)]) -except: +except EG: raise EG("eg2", [ValueError(3), TypeError(4)]) -except: +except EG: raise ImportError(5) expected = ( @@ -2638,7 +2639,7 @@ def exc(): except Exception as e: exc = e raise EG("eg", [VE(1), exc, VE(4)]) -except: +except EG: raise EG("top", [VE(5)]) expected = (f' + Exception Group Traceback (most recent call last):\n' @@ -3451,7 +3452,7 @@ def test_long_context_chain(self): def f(): try: 1/0 -except: +except ZeroDivisionError: f() try: @@ -3555,7 +3556,7 @@ def test_comparison_params_variations(self): def raise_exc(): try: raise ValueError('bad value') -except: +except ValueError: raise def raise_with_locals(): ___ 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-125196: Use PyUnicodeWriter in HAMT (#125458)
https://github.com/python/cpython/commit/aa18fd55d575a04e3aa782fedcd08dced26676e0
commit: aa18fd55d575a04e3aa782fedcd08dced26676e0
branch: main
author: Victor Stinner
committer: vstinner
date: 2024-10-15T09:47:36Z
summary:
gh-125196: Use PyUnicodeWriter in HAMT (#125458)
files:
M Python/hamt.c
diff --git a/Python/hamt.c b/Python/hamt.c
index a8fbb00b807934..cfd211f4541446 100644
--- a/Python/hamt.c
+++ b/Python/hamt.c
@@ -349,7 +349,7 @@ hamt_node_find(PyHamtNode *node,
#ifdef Py_DEBUG
static int
hamt_node_dump(PyHamtNode *node,
- _PyUnicodeWriter *writer, int level);
+ PyUnicodeWriter *writer, int level);
#endif
static PyHamtNode *
@@ -444,7 +444,7 @@ hamt_bitindex(uint32_t bitmap, uint32_t bit)
#ifdef Py_DEBUG
static int
-_hamt_dump_ident(_PyUnicodeWriter *writer, int level)
+_hamt_dump_ident(PyUnicodeWriter *writer, int level)
{
/* Write `'' * level` to the `writer` */
PyObject *str = NULL;
@@ -467,7 +467,7 @@ _hamt_dump_ident(_PyUnicodeWriter *writer, int level)
goto error;
}
-ret = _PyUnicodeWriter_WriteStr(writer, res);
+ret = PyUnicodeWriter_WriteStr(writer, res);
error:
Py_XDECREF(res);
@@ -476,29 +476,6 @@ _hamt_dump_ident(_PyUnicodeWriter *writer, int level)
return ret;
}
-static int
-_hamt_dump_format(_PyUnicodeWriter *writer, const char *format, ...)
-{
-/* A convenient helper combining _PyUnicodeWriter_WriteStr and
- PyUnicode_FromFormatV.
-*/
-PyObject* msg;
-int ret;
-
-va_list vargs;
-va_start(vargs, format);
-msg = PyUnicode_FromFormatV(format, vargs);
-va_end(vargs);
-
-if (msg == NULL) {
-return -1;
-}
-
-ret = _PyUnicodeWriter_WriteStr(writer, msg);
-Py_DECREF(msg);
-return ret;
-}
-
#endif /* Py_DEBUG */
/// Bitmap Node
@@ -1154,7 +1131,7 @@ hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self)
#ifdef Py_DEBUG
static int
hamt_node_bitmap_dump(PyHamtNode_Bitmap *node,
- _PyUnicodeWriter *writer, int level)
+ PyUnicodeWriter *writer, int level)
{
/* Debug build: __dump__() method implementation for Bitmap nodes. */
@@ -1166,8 +1143,8 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node,
goto error;
}
-if (_hamt_dump_format(writer, "BitmapNode(size=%zd count=%zd ",
- Py_SIZE(node), Py_SIZE(node) / 2))
+if (PyUnicodeWriter_Format(writer, "BitmapNode(size=%zd count=%zd ",
+ Py_SIZE(node), Py_SIZE(node) / 2) < 0)
{
goto error;
}
@@ -1181,7 +1158,9 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node,
if (tmp2 == NULL) {
goto error;
}
-if (_hamt_dump_format(writer, "bitmap=%S id=%p):\n", tmp2, node)) {
+if (PyUnicodeWriter_Format(writer, "bitmap=%S id=%p):\n",
+ tmp2, node) < 0)
+{
Py_DECREF(tmp2);
goto error;
}
@@ -1196,7 +1175,7 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node,
}
if (key_or_null == NULL) {
-if (_hamt_dump_format(writer, "NULL:\n")) {
+if (PyUnicodeWriter_WriteUTF8(writer, "NULL:\n", -1) < 0) {
goto error;
}
@@ -1207,14 +1186,14 @@ hamt_node_bitmap_dump(PyHamtNode_Bitmap *node,
}
}
else {
-if (_hamt_dump_format(writer, "%R: %R", key_or_null,
- val_or_node))
+if (PyUnicodeWriter_Format(writer, "%R: %R",
+ key_or_null, val_or_node) < 0)
{
goto error;
}
}
-if (_hamt_dump_format(writer, "\n")) {
+if (PyUnicodeWriter_WriteUTF8(writer, "\n", 1) < 0) {
goto error;
}
}
@@ -1548,7 +1527,7 @@ hamt_node_collision_dealloc(PyHamtNode_Collision *self)
#ifdef Py_DEBUG
static int
hamt_node_collision_dump(PyHamtNode_Collision *node,
- _PyUnicodeWriter *writer, int level)
+ PyUnicodeWriter *writer, int level)
{
/* Debug build: __dump__() method implementation for Collision nodes. */
@@ -1558,8 +1537,8 @@ hamt_node_collision_dump(PyHamtNode_Collision *node,
goto error;
}
-if (_hamt_dump_format(writer, "CollisionNode(size=%zd id=%p):\n",
- Py_SIZE(node), node))
+if (PyUnicodeWriter_Format(writer, "CollisionNode(size=%zd id=%p):\n",
+ Py_SIZE(node), node) < 0)
{
goto error;
}
@@ -1572,7 +1551,7 @@ hamt_node_collision_dump(PyHamtNode_Collision *node,
goto error;
}
-if (_hamt_dump_format(writer, "%R: %R\n", key, val)) {
+if (PyUnicodeWriter_Format(writer, "%R: %R\n", key, val) < 0) {
goto error;
}
}
@@ -1924,7 +1903,7 @@ hamt_node_array_dealloc(PyHamtNode_Array *se
[Python-checkins] gh-119535: Support 𝜋thon in Python 3.14 venvs (#125035)
https://github.com/python/cpython/commit/fcef3fc9a593e2aa868d23cf2d91c57d8bf60ac6 commit: fcef3fc9a593e2aa868d23cf2d91c57d8bf60ac6 branch: main author: foreignmeloman committer: hugovk <[email protected]> date: 2024-10-15T13:26:19+03:00 summary: gh-119535: Support 𝜋thon in Python 3.14 venvs (#125035) files: M Lib/venv/__init__.py diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index a00fa690fa0b88..a5d348ba4cf121 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -306,7 +306,7 @@ def setup_python(self, context): suffixes = ['python', 'python3', f'python3.{sys.version_info[1]}'] if sys.version_info[:2] == (3, 14): -suffixes.append('python𝜋') +suffixes.append('𝜋thon') for suffix in suffixes: path = os.path.join(binpath, suffix) if not os.path.exists(path): ___ 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-123299: Copyedit "What's New in Python 3.14" (#125438)
https://github.com/python/cpython/commit/66064c342c6fb54b443aae8ccf8db74bb9d8bc50 commit: 66064c342c6fb54b443aae8ccf8db74bb9d8bc50 branch: main author: Hugo van Kemenade <[email protected]> committer: hugovk <[email protected]> date: 2024-10-15T10:39:15+03:00 summary: gh-123299: Copyedit "What's New in Python 3.14" (#125438) files: M Doc/deprecations/c-api-pending-removal-in-3.14.rst M Doc/deprecations/c-api-pending-removal-in-3.15.rst M Doc/deprecations/c-api-pending-removal-in-future.rst M Doc/deprecations/index.rst M Doc/deprecations/pending-removal-in-3.13.rst M Doc/deprecations/pending-removal-in-3.14.rst M Doc/deprecations/pending-removal-in-3.15.rst M Doc/deprecations/pending-removal-in-3.16.rst M Doc/deprecations/pending-removal-in-future.rst M Doc/whatsnew/3.14.rst diff --git a/Doc/deprecations/c-api-pending-removal-in-3.14.rst b/Doc/deprecations/c-api-pending-removal-in-3.14.rst index d16da66c29abe7..9e10bf2691e5c8 100644 --- a/Doc/deprecations/c-api-pending-removal-in-3.14.rst +++ b/Doc/deprecations/c-api-pending-removal-in-3.14.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.14 +Pending removal in Python 3.14 ^^ * The ``ma_version_tag`` field in :c:type:`PyDictObject` for extension modules diff --git a/Doc/deprecations/c-api-pending-removal-in-3.15.rst b/Doc/deprecations/c-api-pending-removal-in-3.15.rst index e3974415e0cc89..1bb49e5b4874f2 100644 --- a/Doc/deprecations/c-api-pending-removal-in-3.15.rst +++ b/Doc/deprecations/c-api-pending-removal-in-3.15.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.15 +Pending removal in Python 3.15 ^^ * The bundled copy of ``libmpdecimal``. diff --git a/Doc/deprecations/c-api-pending-removal-in-future.rst b/Doc/deprecations/c-api-pending-removal-in-future.rst index 0c3ae52b87ff74..8fc1c80c35d092 100644 --- a/Doc/deprecations/c-api-pending-removal-in-future.rst +++ b/Doc/deprecations/c-api-pending-removal-in-future.rst @@ -1,4 +1,4 @@ -Pending Removal in Future Versions +Pending removal in future versions ^^ The following APIs are deprecated and will be removed, diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst index a9efb0bc744335..bac6e3f18d4594 100644 --- a/Doc/deprecations/index.rst +++ b/Doc/deprecations/index.rst @@ -7,7 +7,7 @@ Deprecations .. include:: pending-removal-in-future.rst -C API Deprecations +C API deprecations -- .. include:: c-api-pending-removal-in-3.15.rst diff --git a/Doc/deprecations/pending-removal-in-3.13.rst b/Doc/deprecations/pending-removal-in-3.13.rst index 89790497816e83..2fd2f12cc6a2c4 100644 --- a/Doc/deprecations/pending-removal-in-3.13.rst +++ b/Doc/deprecations/pending-removal-in-3.13.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.13 +Pending removal in Python 3.13 -- Modules (see :pep:`594`): diff --git a/Doc/deprecations/pending-removal-in-3.14.rst b/Doc/deprecations/pending-removal-in-3.14.rst index de30f4695059ed..b8791b8d6c387e 100644 --- a/Doc/deprecations/pending-removal-in-3.14.rst +++ b/Doc/deprecations/pending-removal-in-3.14.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.14 +Pending removal in Python 3.14 -- * The import system: diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst index a55fb6bea3fdaa..17029b8d4773bd 100644 --- a/Doc/deprecations/pending-removal-in-3.15.rst +++ b/Doc/deprecations/pending-removal-in-3.15.rst @@ -1,4 +1,4 @@ -Pending Removal in Python 3.15 +Pending removal in Python 3.15 -- * The import system: @@ -63,7 +63,7 @@ Pending Removal in Python 3.15 * The undocumented keyword argument syntax for creating :class:`~typing.NamedTuple` classes -(e.g. ``Point = NamedTuple("Point", x=int, y=int)``) +(for example, ``Point = NamedTuple("Point", x=int, y=int)``) has been deprecated since Python 3.13. Use the class-based syntax or the functional syntax instead. diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst index fc2ef33de5e5cc..fac500d34742ca 100644 --- a/Doc/deprecations/pending-removal-in-3.16.rst +++ b/Doc/deprecations/pending-removal-in-3.16.rst @@ -1,15 +1,6 @@ -Pending Removal in Python 3.16 +Pending removal in Python 3.16 -- -* :mod:`builtins`: - - * Bitwise inversion on boolean types, ``~True`` or ``~False`` -has been deprecated since Python 3.12, -as it produces surprising and unintuitive results (``-2`` and ``-1``). -Use ``not x`` instead for the logical negation of a Boolean. -In the rare case that you need the bitwise inversion of -the underlying integer, convert to ``int`` explicitly (``~int(x)``). - * :mod:`array`: * The ``'u'`` format code (:c:type:`wchar_t`) @@ -20,11 +11,19 @@ Pending Remov
[Python-checkins] [3.13] Doc: Update CVE URL (GH-125489) (#125503)
https://github.com/python/cpython/commit/4bc59e5fd7add7c8a60f3636853163d1d5806ce0 commit: 4bc59e5fd7add7c8a60f3636853163d1d5806ce0 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: hugovk <[email protected]> date: 2024-10-15T07:34:15Z summary: [3.13] Doc: Update CVE URL (GH-125489) (#125503) Co-authored-by: Mariusz Felisiak files: M Doc/conf.py diff --git a/Doc/conf.py b/Doc/conf.py index d7197b17865854..839beaad08bebd 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -614,7 +614,7 @@ # Sphinx 8.1 has in-built CVE and CWE roles. extlinks |= { "cve": ( -"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s";, +"https://www.cve.org/CVERecord?id=CVE-%s";, "CVE-%s", ), "cwe": ("https://cwe.mitre.org/data/definitions/%s.html";, "CWE-%s"), ___ 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] Doc: Update CVE URL (#125489)
https://github.com/python/cpython/commit/a2fe9ff11d6104074c19bf328a104caa99becc11 commit: a2fe9ff11d6104074c19bf328a104caa99becc11 branch: main author: Mariusz Felisiak committer: hugovk <[email protected]> date: 2024-10-15T10:29:08+03:00 summary: Doc: Update CVE URL (#125489) files: M Doc/conf.py diff --git a/Doc/conf.py b/Doc/conf.py index d7197b17865854..839beaad08bebd 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -614,7 +614,7 @@ # Sphinx 8.1 has in-built CVE and CWE roles. extlinks |= { "cve": ( -"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s";, +"https://www.cve.org/CVERecord?id=CVE-%s";, "CVE-%s", ), "cwe": ("https://cwe.mitre.org/data/definitions/%s.html";, "CWE-%s"), ___ 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] Doc: Update CVE URL (GH-125489) (#125504)
https://github.com/python/cpython/commit/79422bc13b17331211619354b7d8acaccafcc79a commit: 79422bc13b17331211619354b7d8acaccafcc79a branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: hugovk <[email protected]> date: 2024-10-15T07:36:17Z summary: [3.12] Doc: Update CVE URL (GH-125489) (#125504) Co-authored-by: Mariusz Felisiak files: M Doc/conf.py diff --git a/Doc/conf.py b/Doc/conf.py index 36f6243969c8b2..fb55c5c65c2f35 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -593,7 +593,7 @@ # Sphinx 8.1 has in-built CVE and CWE roles. extlinks |= { "cve": ( -"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s";, +"https://www.cve.org/CVERecord?id=CVE-%s";, "CVE-%s", ), "cwe": ("https://cwe.mitre.org/data/definitions/%s.html";, "CWE-%s"), ___ 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-53203: Fix strptime() tests for %X on glibc < 2.29 (#125469)
https://github.com/python/cpython/commit/92af191a6a5f266b71373f5374ca0c9c522d62d9 commit: 92af191a6a5f266b71373f5374ca0c9c522d62d9 branch: main author: Serhiy Storchaka committer: hugovk <[email protected]> date: 2024-10-15T11:05:40+03:00 summary: gh-53203: Fix strptime() tests for %X on glibc < 2.29 (#125469) files: M Lib/test/test_strptime.py diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 12366b053a2fc1..09f6f656bfcb0d 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -569,12 +569,20 @@ def test_date_locale2(self): 'ti_ET', 'tig_ER', 'wal_ET') def test_time_locale(self): # Test %X directive +loc = locale.getlocale(locale.LC_TIME)[0] +pos = slice(3, 6) +if glibc_ver and glibc_ver < (2, 29) and loc in { +'aa_ET', 'am_ET', 'byn_ER', 'gez_ET', 'om_ET', +'sid_ET', 'so_SO', 'ti_ET', 'tig_ER', 'wal_ET'}: +# Hours are in 12-hour notation without AM/PM indication. +# Ignore hours. +pos = slice(4, 6) now = time.time() -self.roundtrip('%X', slice(3, 6), time.localtime(now)) +self.roundtrip('%X', pos, time.localtime(now)) # 1 hour 20 minutes 30 seconds ago -self.roundtrip('%X', slice(3, 6), time.localtime(now - 4830)) +self.roundtrip('%X', pos, time.localtime(now - 4830)) # 12 hours ago -self.roundtrip('%X', slice(3, 6), time.localtime(now - 12*3600)) +self.roundtrip('%X', pos, time.localtime(now - 12*3600)) def test_percent(self): # Make sure % signs are handled properly ___ 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-124594: Create and reuse the same context for the entire asyncio REPL session (GH-124595) (#124848)
https://github.com/python/cpython/commit/35d96241091f5bd477c942e0f1b174c0bdae5596 commit: 35d96241091f5bd477c942e0f1b174c0bdae5596 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: asvetlov date: 2024-10-15T13:37:59+02:00 summary: [3.13] gh-124594: Create and reuse the same context for the entire asyncio REPL session (GH-124595) (#124848) gh-124594: Create and reuse the same context for the entire asyncio REPL session (GH-124595) (cherry picked from commit 67e01a430f4ecfcb540d6a29b347966ff4e53454) Co-authored-by: Bartosz Sławecki Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst M Lib/asyncio/__main__.py M Lib/test/test_repl.py diff --git a/Lib/asyncio/__main__.py b/Lib/asyncio/__main__.py index 5120140e061691..95c636f9e02866 100644 --- a/Lib/asyncio/__main__.py +++ b/Lib/asyncio/__main__.py @@ -1,6 +1,7 @@ import ast import asyncio import concurrent.futures +import contextvars import inspect import os import site @@ -22,6 +23,7 @@ def __init__(self, locals, loop): self.compile.compiler.flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT self.loop = loop +self.context = contextvars.copy_context() def runcode(self, code): global return_code @@ -55,12 +57,12 @@ def callback(): return try: -repl_future = self.loop.create_task(coro) +repl_future = self.loop.create_task(coro, context=self.context) futures._chain_future(repl_future, future) except BaseException as exc: future.set_exception(exc) -loop.call_soon_threadsafe(callback) +loop.call_soon_threadsafe(callback, context=self.context) try: return future.result() diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 7a7285a1a2fcfd..e764e60560db23 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -291,5 +291,42 @@ def f(): self.assertEqual(traceback_lines, expected_lines) +class TestAsyncioREPLContextVars(unittest.TestCase): +def test_toplevel_contextvars_sync(self): +user_input = dedent("""\ +from contextvars import ContextVar +var = ContextVar("var", default="failed") +var.set("ok") +""") +p = spawn_repl("-m", "asyncio") +p.stdin.write(user_input) +user_input2 = dedent(""" +print(f"toplevel contextvar test: {var.get()}") +""") +p.stdin.write(user_input2) +output = kill_python(p) +self.assertEqual(p.returncode, 0) +expected = "toplevel contextvar test: ok" +self.assertIn(expected, output, expected) + +def test_toplevel_contextvars_async(self): +user_input = dedent("""\ +from contextvars import ContextVar +var = ContextVar('var', default='failed') +""") +p = spawn_repl("-m", "asyncio") +p.stdin.write(user_input) +user_input2 = "async def set_var(): var.set('ok')\n" +p.stdin.write(user_input2) +user_input3 = "await set_var()\n" +p.stdin.write(user_input3) +user_input4 = "print(f'toplevel contextvar test: {var.get()}')\n" +p.stdin.write(user_input4) +output = kill_python(p) +self.assertEqual(p.returncode, 0) +expected = "toplevel contextvar test: ok" +self.assertIn(expected, output, expected) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst b/Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst new file mode 100644 index 00..ac48bd84930745 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-26-13-43-39.gh-issue-124594.peYhsP.rst @@ -0,0 +1 @@ +All :mod:`asyncio` REPL prompts run in the same :class:`context `. Contributed by Bartosz Sławecki. ___ 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-124375: Avoid calling `_PyMem_ProcessDelayed` on other thread states (GH-124459) (#125540)
https://github.com/python/cpython/commit/4d83f6ddc413204943097699ef84a30356ba8cce commit: 4d83f6ddc413204943097699ef84a30356ba8cce branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: colesbury date: 2024-10-15T13:35:28-04:00 summary: [3.13] gh-124375: Avoid calling `_PyMem_ProcessDelayed` on other thread states (GH-124459) (#125540) This fixes a crash when running the PyO3 test suite on the free-threaded build. The `qsbr` field is initialized after the `PyThreadState` is added to the interpreter's linked list -- it might still be NULL. Instead, we "steal" the queue of to-be-freed memory blocks. This is always initialized (possibly empty) and protected by the stop the world pause. (cherry picked from commit 54c6fcbefd33a8d8bf8c004cf1aad3be3d37b933) Co-authored-by: Sam Gross files: A Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst M Python/gc_free_threading.c diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst new file mode 100644 index 00..4bd17a6e683bc7 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-15-15-29-41.gh-issue-124375.wNrWVa.rst @@ -0,0 +1 @@ +Fix a crash in the free threading build when the GC runs concurrently with a new thread starting. diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 140f1eaa88bfc2..1d8641b91da662 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -340,18 +340,24 @@ merge_all_queued_objects(PyInterpreterState *interp, struct collection_state *st static void process_delayed_frees(PyInterpreterState *interp) { -// In STW status, we can observe the latest write sequence by -// advancing the write sequence immediately. +// While we are in a "stop the world" pause, we can observe the latest +// write sequence by advancing the write sequence immediately. _Py_qsbr_advance(&interp->qsbr); _PyThreadStateImpl *current_tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); _Py_qsbr_quiescent_state(current_tstate->qsbr); + +// Merge the queues from other threads into our own queue so that we can +// process all of the pending delayed free requests at once. HEAD_LOCK(&_PyRuntime); -PyThreadState *tstate = interp->threads.head; -while (tstate != NULL) { -_PyMem_ProcessDelayed(tstate); -tstate = (PyThreadState *)tstate->next; +for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) { +_PyThreadStateImpl *other = (_PyThreadStateImpl *)p; +if (other != current_tstate) { +llist_concat(¤t_tstate->mem_free_queue, &other->mem_free_queue); +} } HEAD_UNLOCK(&_PyRuntime); + +_PyMem_ProcessDelayed((PyThreadState *)current_tstate); } // Subtract an incoming reference from the computed "gc_refs" refcount. ___ 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-125422: Don't set the caller's f_trace if it's botframe (GH-125427) (#125530)
https://github.com/python/cpython/commit/a22e11f8dcfd902f43aa69be34f2a9a89ab514ac commit: a22e11f8dcfd902f43aa69be34f2a9a89ab514ac branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: gaogaotiantian date: 2024-10-15T15:26:46Z summary: [3.13] gh-125422: Don't set the caller's f_trace if it's botframe (GH-125427) (#125530) gh-125422: Don't set the caller's f_trace if it's botframe (GH-125427) (cherry picked from commit 703227dd021491ceb9343f69fa48f4b6a05adbb3) Co-authored-by: Tian Gao files: A Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst M Lib/bdb.py M Lib/test/test_bdb.py M Lib/test/test_pdb.py diff --git a/Lib/bdb.py b/Lib/bdb.py index aa621053cfb4bc..a0e46e7f413816 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -329,9 +329,10 @@ def _set_caller_tracefunc(self, current_frame): # Issue #13183: pdb skips frames after hitting a breakpoint and running # step commands. # Restore the trace function in the caller (that may not have been set -# for performance reasons) when returning from the current frame. +# for performance reasons) when returning from the current frame, unless +# the caller is the botframe. caller_frame = current_frame.f_back -if caller_frame and not caller_frame.f_trace: +if caller_frame and not caller_frame.f_trace and caller_frame is not self.botframe: caller_frame.f_trace = self.trace_dispatch # Derived classes and clients can call the following methods diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index ed1a63daea1186..2e20c08a672d57 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -1216,6 +1216,19 @@ def main(): with TracerRun(self) as tracer: tracer.runcall(tfunc_import) +def test_next_to_botframe(self): +# gh-125422 +# Check that next command won't go to the bottom frame. +code = """ +lno = 2 +""" +self.expect_set = [ +('line', 2, ''), ('step', ), +('return', 2, ''), ('next', ), +] +with TracerRun(self) as tracer: +tracer.run(compile(textwrap.dedent(code), '', 'exec')) + class TestRegressions(unittest.TestCase): def test_format_stack_entry_no_lineno(self): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 9b2c885ed67f85..35285b7706bb70 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3181,6 +3181,20 @@ def test_issue26053(self): self.assertRegex(res, "Restarting .* with arguments:\na b c") self.assertRegex(res, "Restarting .* with arguments:\nd e f") +def test_step_into_botframe(self): +# gh-125422 +# pdb should not be able to step into the botframe (bdb.py) +script = "x = 1" +commands = """ +step +step +step +quit +""" +stdout, _ = self.run_pdb_script(script, commands) +self.assertIn("The program finished", stdout) +self.assertNotIn("bdb.py", stdout) + def test_pdbrc_basic(self): script = textwrap.dedent(""" a = 1 diff --git a/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst new file mode 100644 index 00..c890ecec8beaf8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst @@ -0,0 +1 @@ +Fixed the bug where :mod:`pdb` and :mod:`bdb` can step into the bottom caller frame. ___ 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-125422: Don't set the caller's f_trace if it's botframe (GH-125427) (#125531)
https://github.com/python/cpython/commit/0a82c4cbd8c0b74e6111370d3c498142fdf9f085 commit: 0a82c4cbd8c0b74e6111370d3c498142fdf9f085 branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: gaogaotiantian date: 2024-10-15T15:26:41Z summary: [3.12] gh-125422: Don't set the caller's f_trace if it's botframe (GH-125427) (#125531) gh-125422: Don't set the caller's f_trace if it's botframe (GH-125427) (cherry picked from commit 703227dd021491ceb9343f69fa48f4b6a05adbb3) Co-authored-by: Tian Gao files: A Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst M Lib/bdb.py M Lib/test/test_bdb.py M Lib/test/test_pdb.py diff --git a/Lib/bdb.py b/Lib/bdb.py index 564d6c5e5324ed..196e6b178cb9fd 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -295,9 +295,10 @@ def _set_caller_tracefunc(self, current_frame): # Issue #13183: pdb skips frames after hitting a breakpoint and running # step commands. # Restore the trace function in the caller (that may not have been set -# for performance reasons) when returning from the current frame. +# for performance reasons) when returning from the current frame, unless +# the caller is the botframe. caller_frame = current_frame.f_back -if caller_frame and not caller_frame.f_trace: +if caller_frame and not caller_frame.f_trace and caller_frame is not self.botframe: caller_frame.f_trace = self.trace_dispatch # Derived classes and clients can call the following methods diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index 568c88e326c087..33e28592f59e1b 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -1203,6 +1203,19 @@ def main(): with TracerRun(self) as tracer: tracer.runcall(tfunc_import) +def test_next_to_botframe(self): +# gh-125422 +# Check that next command won't go to the bottom frame. +code = """ +lno = 2 +""" +self.expect_set = [ +('line', 2, ''), ('step', ), +('return', 2, ''), ('next', ), +] +with TracerRun(self) as tracer: +tracer.run(compile(textwrap.dedent(code), '', 'exec')) + class TestRegressions(unittest.TestCase): def test_format_stack_entry_no_lineno(self): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 8a7e41b281165e..6da82fe04c0eaa 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -2283,6 +2283,20 @@ def test_issue26053(self): self.assertRegex(res, "Restarting .* with arguments:\na b c") self.assertRegex(res, "Restarting .* with arguments:\nd e f") +def test_step_into_botframe(self): +# gh-125422 +# pdb should not be able to step into the botframe (bdb.py) +script = "x = 1" +commands = """ +step +step +step +quit +""" +stdout, _ = self.run_pdb_script(script, commands) +self.assertIn("The program finished", stdout) +self.assertNotIn("bdb.py", stdout) + def test_pdbrc_basic(self): script = textwrap.dedent(""" a = 1 diff --git a/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst new file mode 100644 index 00..c890ecec8beaf8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst @@ -0,0 +1 @@ +Fixed the bug where :mod:`pdb` and :mod:`bdb` can step into the bottom caller frame. ___ 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-125422: Don't set the caller's f_trace if it's botframe (#125427)
https://github.com/python/cpython/commit/703227dd021491ceb9343f69fa48f4b6a05adbb3
commit: 703227dd021491ceb9343f69fa48f4b6a05adbb3
branch: main
author: Tian Gao
committer: gaogaotiantian
date: 2024-10-15T10:51:37-04:00
summary:
gh-125422: Don't set the caller's f_trace if it's botframe (#125427)
files:
A Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst
M Lib/bdb.py
M Lib/test/test_bdb.py
M Lib/test/test_pdb.py
diff --git a/Lib/bdb.py b/Lib/bdb.py
index 666f9714eb9b7a..9755d61dd2696c 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -350,9 +350,10 @@ def _set_caller_tracefunc(self, current_frame):
# Issue #13183: pdb skips frames after hitting a breakpoint and running
# step commands.
# Restore the trace function in the caller (that may not have been set
-# for performance reasons) when returning from the current frame.
+# for performance reasons) when returning from the current frame,
unless
+# the caller is the botframe.
caller_frame = current_frame.f_back
-if caller_frame and not caller_frame.f_trace:
+if caller_frame and not caller_frame.f_trace and caller_frame is not
self.botframe:
caller_frame.f_trace = self.trace_dispatch
# Derived classes and clients can call the following methods
diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py
index 10c58c04dfd25e..f15dae13eb384e 100644
--- a/Lib/test/test_bdb.py
+++ b/Lib/test/test_bdb.py
@@ -1217,6 +1217,19 @@ def main():
with TracerRun(self) as tracer:
tracer.runcall(tfunc_import)
+def test_next_to_botframe(self):
+# gh-125422
+# Check that next command won't go to the bottom frame.
+code = """
+lno = 2
+"""
+self.expect_set = [
+('line', 2, ''), ('step', ),
+('return', 2, ''), ('next', ),
+]
+with TracerRun(self) as tracer:
+tracer.run(compile(textwrap.dedent(code), '', 'exec'))
+
class TestRegressions(unittest.TestCase):
def test_format_stack_entry_no_lineno(self):
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 46eb00261042bc..3dc65fdfc03409 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -3393,6 +3393,20 @@ def test_issue26053(self):
self.assertRegex(res, "Restarting .* with arguments:\na b c")
self.assertRegex(res, "Restarting .* with arguments:\nd e f")
+def test_step_into_botframe(self):
+# gh-125422
+# pdb should not be able to step into the botframe (bdb.py)
+script = "x = 1"
+commands = """
+step
+step
+step
+quit
+"""
+stdout, _ = self.run_pdb_script(script, commands)
+self.assertIn("The program finished", stdout)
+self.assertNotIn("bdb.py", stdout)
+
def test_pdbrc_basic(self):
script = textwrap.dedent("""
a = 1
diff --git
a/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst
b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst
new file mode 100644
index 00..c890ecec8beaf8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-14-04-44-12.gh-issue-125422.MlVuC6.rst
@@ -0,0 +1 @@
+Fixed the bug where :mod:`pdb` and :mod:`bdb` can step into the bottom caller
frame.
___
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-100141: Allow pdb to deal with empty file (GH-125425) (#125536)
https://github.com/python/cpython/commit/6c79baea4dbd0497253015bb8e8ffe96c39c31b0 commit: 6c79baea4dbd0497253015bb8e8ffe96c39c31b0 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: gaogaotiantian date: 2024-10-15T16:28:57Z summary: [3.13] gh-100141: Allow pdb to deal with empty file (GH-125425) (#125536) gh-100141: Allow pdb to deal with empty file (GH-125425) (cherry picked from commit bb9604b62ae7f043594ffea9287f9213067cc7fb) Co-authored-by: Tian Gao files: A Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst M Lib/pdb.py M Lib/test/test_pdb.py diff --git a/Lib/pdb.py b/Lib/pdb.py index a42b8881f036f0..169eb0e49c4a31 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -429,8 +429,7 @@ def user_call(self, frame, argument_list): def user_line(self, frame): """This function is called when we stop or break at this line.""" if self._wait_for_mainpyfile: -if (self.mainpyfile != self.canonic(frame.f_code.co_filename) -or frame.f_lineno <= 0): +if (self.mainpyfile != self.canonic(frame.f_code.co_filename)): return self._wait_for_mainpyfile = False if self.bp_commands(frame): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 35285b7706bb70..266141e566a1ed 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3781,6 +3781,16 @@ def _create_fake_frozen_module(): # verify that pdb found the source of the "frozen" function self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel statement not found") +def test_empty_file(self): +script = '' +commands = 'q\n' +# We check that pdb stopped at line 0, but anything reasonable +# is acceptable here, as long as it does not halt +stdout, _ = self.run_pdb_script(script, commands) +self.assertIn('main.py(0)', stdout) +stdout, _ = self.run_pdb_module(script, commands) +self.assertIn('__main__.py(0)', stdout) + def test_non_utf8_encoding(self): script_dir = os.path.join(os.path.dirname(__file__), 'encoded_modules') for filename in os.listdir(script_dir): diff --git a/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst new file mode 100644 index 00..c366b0ad4040d3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst @@ -0,0 +1 @@ +Fixed the bug where :mod:`pdb` will be stuck in an infinite loop when debugging an empty file. ___ 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-100141: Allow pdb to deal with empty file (GH-125425) (#125537)
https://github.com/python/cpython/commit/90b1406b881aa0a57ce3a73c402b73b79138b7e0 commit: 90b1406b881aa0a57ce3a73c402b73b79138b7e0 branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: gaogaotiantian date: 2024-10-15T16:29:05Z summary: [3.12] gh-100141: Allow pdb to deal with empty file (GH-125425) (#125537) gh-100141: Allow pdb to deal with empty file (GH-125425) (cherry picked from commit bb9604b62ae7f043594ffea9287f9213067cc7fb) Co-authored-by: Tian Gao files: A Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst M Lib/pdb.py M Lib/test/test_pdb.py diff --git a/Lib/pdb.py b/Lib/pdb.py index 89cf975164ac04..559517813cf600 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -321,8 +321,7 @@ def user_call(self, frame, argument_list): def user_line(self, frame): """This function is called when we stop or break at this line.""" if self._wait_for_mainpyfile: -if (self.mainpyfile != self.canonic(frame.f_code.co_filename) -or frame.f_lineno <= 0): +if (self.mainpyfile != self.canonic(frame.f_code.co_filename)): return self._wait_for_mainpyfile = False if self.bp_commands(frame): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 6da82fe04c0eaa..1542bb3bee1aea 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -2754,6 +2754,16 @@ def _create_fake_frozen_module(): # verify that pdb found the source of the "frozen" function self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel statement not found") +def test_empty_file(self): +script = '' +commands = 'q\n' +# We check that pdb stopped at line 0, but anything reasonable +# is acceptable here, as long as it does not halt +stdout, _ = self.run_pdb_script(script, commands) +self.assertIn('main.py(0)', stdout) +stdout, _ = self.run_pdb_module(script, commands) +self.assertIn('__main__.py(0)', stdout) + def test_non_utf8_encoding(self): script_dir = os.path.join(os.path.dirname(__file__), 'encoded_modules') for filename in os.listdir(script_dir): diff --git a/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst new file mode 100644 index 00..c366b0ad4040d3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-14-02-27-03.gh-issue-100141.NuAcwa.rst @@ -0,0 +1 @@ +Fixed the bug where :mod:`pdb` will be stuck in an infinite loop when debugging an empty file. ___ 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-125115: Pass unknown pdb command line args to script instead of fail (GH-125424) (#125547)
https://github.com/python/cpython/commit/c5bad759f5b0d23e0ab9a40b3fa9dd4c77748cb7 commit: c5bad759f5b0d23e0ab9a40b3fa9dd4c77748cb7 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: gaogaotiantian date: 2024-10-15T19:55:38Z summary: [3.13] gh-125115: Pass unknown pdb command line args to script instead of fail (GH-125424) (#125547) gh-125115: Pass unknown pdb command line args to script instead of fail (GH-125424) (cherry picked from commit 9c2bb7d551a695f35db953a671a2ddca89426bef) Co-authored-by: Tian Gao Co-authored-by: Irit Katriel <[email protected]> files: A Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst M Lib/pdb.py M Lib/test/test_pdb.py diff --git a/Lib/pdb.py b/Lib/pdb.py index 169eb0e49c4a31..a987ea7afebfa7 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -84,6 +84,7 @@ import inspect import textwrap import tokenize +import itertools import traceback import linecache import _colorize @@ -2414,8 +2415,6 @@ def main(): parser.add_argument('-c', '--command', action='append', default=[], metavar='command', dest='commands', help='pdb commands to execute as if given in a .pdbrc file') parser.add_argument('-m', metavar='module', dest='module') -parser.add_argument('args', nargs='*', -help="when -m is not specified, the first arg is the script to debug") if len(sys.argv) == 1: # If no arguments were given (python -m pdb), print the whole help message. @@ -2423,21 +2422,40 @@ def main(): parser.print_help() sys.exit(2) -opts = parser.parse_args() +opts, args = parser.parse_known_args() + +if opts.module: +# If a module is being debugged, we consider the arguments after "-m module" to +# be potential arguments to the module itself. We need to parse the arguments +# before "-m" to check if there is any invalid argument. +# e.g. "python -m pdb -m foo --spam" means passing "--spam" to "foo" +# "python -m pdb --spam -m foo" means passing "--spam" to "pdb" and is invalid +idx = sys.argv.index('-m') +args_to_pdb = sys.argv[1:idx] +# This will raise an error if there are invalid arguments +parser.parse_args(args_to_pdb) +else: +# If a script is being debugged, then pdb expects the script name as the first argument. +# Anything before the script is considered an argument to pdb itself, which would +# be invalid because it's not parsed by argparse. +invalid_args = list(itertools.takewhile(lambda a: a.startswith('-'), args)) +if invalid_args: +parser.error(f"unrecognized arguments: {' '.join(invalid_args)}") +sys.exit(2) if opts.module: file = opts.module target = _ModuleTarget(file) else: -if not opts.args: +if not args: parser.error("no module or script to run") -file = opts.args.pop(0) +file = args.pop(0) if file.endswith('.pyz'): target = _ZipTarget(file) else: target = _ScriptTarget(file) -sys.argv[:] = [file] + opts.args # Hide "pdb.py" and pdb options from argument list +sys.argv[:] = [file] + args # Hide "pdb.py" and pdb options from argument list # Note on saving/restoring sys.argv: it's a good idea when sys.argv was # modified by the script being debugged. It's a bad idea when it was diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 266141e566a1ed..5fe03cc33f34be 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -2877,6 +2877,7 @@ def _run_pdb(self, pdb_args, commands, def run_pdb_script(self, script, commands, expected_returncode=0, extra_env=None, + script_args=None, pdbrc=None, remove_home=False): """Run 'script' lines with pdb and the pdb 'commands'.""" @@ -2894,7 +2895,9 @@ def run_pdb_script(self, script, commands, if remove_home: homesave = os.environ.pop('HOME', None) try: -stdout, stderr = self._run_pdb([filename], commands, expected_returncode, extra_env) +if script_args is None: +script_args = [] +stdout, stderr = self._run_pdb([filename] + script_args, commands, expected_returncode, extra_env) finally: if homesave is not None: os.environ['HOME'] = homesave @@ -3341,6 +3344,22 @@ def test_run_module_with_args(self): stdout, _ = self._run_pdb(["-m", "calendar", "1"], commands) self.assertIn("December", stdout) +stdout, _ = self._run_pdb(["-m", "calendar", "--type", "text"], commands) +self.assertIn("December", stdout) + +def test_run_script_with_args(self): +
[Python-checkins] Update verison options in crash issue template (GH-125555)
https://github.com/python/cpython/commit/7453b8f15c77a8f3b07a5049450436079476c465 commit: 7453b8f15c77a8f3b07a5049450436079476c465 branch: main author: Zachary Ware committer: zware date: 2024-10-15T22:08:00Z summary: Update verison options in crash issue template (GH-12) files: M .github/ISSUE_TEMPLATE/crash.yml diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml index 6d73f7cae5c0ae..58da2dfe0c7354 100644 --- a/.github/ISSUE_TEMPLATE/crash.yml +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -27,12 +27,12 @@ body: label: "CPython versions tested on:" multiple: true options: -- "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" +- "3.14" - "CPython main branch" validations: required: true ___ 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-125243: Fix ZoneInfo data race in free threading build (GH-125281) (gh-125414)
https://github.com/python/cpython/commit/6474e296c04f136c9d664c899d126795f280ff11 commit: 6474e296c04f136c9d664c899d126795f280ff11 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: colesbury date: 2024-10-15T17:02:32-04:00 summary: [3.13] gh-125243: Fix ZoneInfo data race in free threading build (GH-125281) (gh-125414) Lock `ZoneInfoType` to protect accesses to `ZONEINFO_STRONG_CACHE`. Refactor the `tp_new` handler to use Argument Clinic so that we can just use `@critical_section` annotations on the relevant functions. Also use `PyDict_SetDefaultRef` instead of `PyDict_SetDefault` when inserting into the `TIMEDELTA_CACHE`. (cherry picked from commit f1d33dbddd3496b062e1fbe024fb6d7b023a35f5) Co-authored-by: Sam Gross files: A Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst M Modules/_zoneinfo.c M Modules/clinic/_zoneinfo.c.h diff --git a/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst b/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst new file mode 100644 index 00..49f84d9711819f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-10-20-39-57.gh-issue-125243.eUbbtu.rst @@ -0,0 +1,2 @@ +Fix data race when creating :class:`zoneinfo.ZoneInfo` objects in the free +threading build. diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 902ece795b575b..c5292575c22f23 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -3,6 +3,7 @@ #endif #include "Python.h" +#include "pycore_critical_section.h" // _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() @@ -298,15 +299,20 @@ get_weak_cache(zoneinfo_state *state, PyTypeObject *type) } } +/*[clinic input] +@critical_section +@classmethod +zoneinfo.ZoneInfo.__new__ + +key: object + +Create a new ZoneInfo instance. +[clinic start generated code]*/ + static PyObject * -zoneinfo_new(PyTypeObject *type, PyObject *args, PyObject *kw) +zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key) +/*[clinic end generated code: output=95e61dab86bb95c3 input=ef73d7a83bf8790e]*/ { -PyObject *key = NULL; -static char *kwlist[] = {"key", NULL}; -if (PyArg_ParseTupleAndKeywords(args, kw, "O", kwlist, &key) == 0) { -return NULL; -} - zoneinfo_state *state = zoneinfo_get_state_by_self(type); PyObject *instance = zone_from_strong_cache(state, type, key); if (instance != NULL || PyErr_Occurred()) { @@ -467,6 +473,7 @@ zoneinfo_ZoneInfo_no_cache_impl(PyTypeObject *type, PyTypeObject *cls, } /*[clinic input] +@critical_section @classmethod zoneinfo.ZoneInfo.clear_cache @@ -481,7 +488,7 @@ Clear the ZoneInfo cache. static PyObject * zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyTypeObject *cls, PyObject *only_keys) -/*[clinic end generated code: output=114d9b7c8a22e660 input=e32ca3bb396788ba]*/ +/*[clinic end generated code: output=114d9b7c8a22e660 input=35944715df26d24e]*/ { zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); PyObject *weak_cache = get_weak_cache(state, type); @@ -816,14 +823,10 @@ zoneinfo_ZoneInfo__unpickle_impl(PyTypeObject *type, PyTypeObject *cls, /*[clinic end generated code: output=556712fc709deecb input=6ac8c73eed3de316]*/ { if (from_cache) { -PyObject *val_args = PyTuple_Pack(1, key); -if (val_args == NULL) { -return NULL; -} - -PyObject *rv = zoneinfo_new(type, val_args, NULL); - -Py_DECREF(val_args); +PyObject *rv; +Py_BEGIN_CRITICAL_SECTION(type); +rv = zoneinfo_ZoneInfo_impl(type, key); +Py_END_CRITICAL_SECTION(); return rv; } else { @@ -858,8 +861,7 @@ load_timedelta(zoneinfo_state *state, long seconds) 0, seconds, 0, 1, PyDateTimeAPI->DeltaType); if (tmp != NULL) { -rv = PyDict_SetDefault(state->TIMEDELTA_CACHE, pyoffset, tmp); -Py_XINCREF(rv); +PyDict_SetDefaultRef(state->TIMEDELTA_CACHE, pyoffset, tmp, &rv); Py_DECREF(tmp); } } @@ -2368,6 +2370,7 @@ strong_cache_free(StrongCacheNode *root) static void remove_from_strong_cache(zoneinfo_state *state, StrongCacheNode *node) { +_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(state->ZoneInfoType); if (state->ZONEINFO_STRONG_CACHE == node) { state->ZONEINFO_STRONG_CACHE = node->next; } @@ -2422,6 +2425,7 @@ eject_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, return 0; } +_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(state->ZoneInfoType); StrongCacheNode *cache = state->ZONEINFO_STRONG_CACHE; StrongCacheNode *node = find_in_strong_cache(cache, key); if (node != NULL) { @@ -2478,6 +2482,7 @@ zone_from_strong_cache(zoneinfo_state *state, const
[Python-checkins] gh-125115: Pass unknown pdb command line args to script instead of fail (#125424)
https://github.com/python/cpython/commit/9c2bb7d551a695f35db953a671a2ddca89426bef commit: 9c2bb7d551a695f35db953a671a2ddca89426bef branch: main author: Tian Gao committer: gaogaotiantian date: 2024-10-15T15:30:28-04:00 summary: gh-125115: Pass unknown pdb command line args to script instead of fail (#125424) Co-authored-by: Irit Katriel <[email protected]> files: A Misc/NEWS.d/next/Library/2024-10-14-02-07-44.gh-issue-125115.IOf3ON.rst M Lib/pdb.py M Lib/test/test_pdb.py diff --git a/Lib/pdb.py b/Lib/pdb.py index 2b36b1e3fa7cbe..3e5e6088fdcc7e 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -82,6 +82,7 @@ import inspect import textwrap import tokenize +import itertools import traceback import linecache import _colorize @@ -2433,8 +2434,6 @@ def main(): parser.add_argument('-c', '--command', action='append', default=[], metavar='command', dest='commands', help='pdb commands to execute as if given in a .pdbrc file') parser.add_argument('-m', metavar='module', dest='module') -parser.add_argument('args', nargs='*', -help="when -m is not specified, the first arg is the script to debug") if len(sys.argv) == 1: # If no arguments were given (python -m pdb), print the whole help message. @@ -2442,21 +2441,40 @@ def main(): parser.print_help() sys.exit(2) -opts = parser.parse_args() +opts, args = parser.parse_known_args() + +if opts.module: +# If a module is being debugged, we consider the arguments after "-m module" to +# be potential arguments to the module itself. We need to parse the arguments +# before "-m" to check if there is any invalid argument. +# e.g. "python -m pdb -m foo --spam" means passing "--spam" to "foo" +# "python -m pdb --spam -m foo" means passing "--spam" to "pdb" and is invalid +idx = sys.argv.index('-m') +args_to_pdb = sys.argv[1:idx] +# This will raise an error if there are invalid arguments +parser.parse_args(args_to_pdb) +else: +# If a script is being debugged, then pdb expects the script name as the first argument. +# Anything before the script is considered an argument to pdb itself, which would +# be invalid because it's not parsed by argparse. +invalid_args = list(itertools.takewhile(lambda a: a.startswith('-'), args)) +if invalid_args: +parser.error(f"unrecognized arguments: {' '.join(invalid_args)}") +sys.exit(2) if opts.module: file = opts.module target = _ModuleTarget(file) else: -if not opts.args: +if not args: parser.error("no module or script to run") -file = opts.args.pop(0) +file = args.pop(0) if file.endswith('.pyz'): target = _ZipTarget(file) else: target = _ScriptTarget(file) -sys.argv[:] = [file] + opts.args # Hide "pdb.py" and pdb options from argument list +sys.argv[:] = [file] + args # Hide "pdb.py" and pdb options from argument list # Note on saving/restoring sys.argv: it's a good idea when sys.argv was # modified by the script being debugged. It's a bad idea when it was diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 084b7cd4cad219..456effc010954a 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3089,6 +3089,7 @@ def _run_pdb(self, pdb_args, commands, def run_pdb_script(self, script, commands, expected_returncode=0, extra_env=None, + script_args=None, pdbrc=None, remove_home=False): """Run 'script' lines with pdb and the pdb 'commands'.""" @@ -3106,7 +3107,9 @@ def run_pdb_script(self, script, commands, if remove_home: homesave = os.environ.pop('HOME', None) try: -stdout, stderr = self._run_pdb([filename], commands, expected_returncode, extra_env) +if script_args is None: +script_args = [] +stdout, stderr = self._run_pdb([filename] + script_args, commands, expected_returncode, extra_env) finally: if homesave is not None: os.environ['HOME'] = homesave @@ -3559,6 +3562,22 @@ def test_run_module_with_args(self): stdout, _ = self._run_pdb(["-m", "calendar", "1"], commands) self.assertIn("December", stdout) +stdout, _ = self._run_pdb(["-m", "calendar", "--type", "text"], commands) +self.assertIn("December", stdout) + +def test_run_script_with_args(self): +script = """ +import sys +print(sys.argv[1:]) +""" +commands = """ +continue +quit +""" + +stdout, stderr = self.run_pdb_script(script, commands, script_args=["--bar", "foo
[Python-checkins] gh-58956: Set f_trace on frames with breakpoints after setting a new breakpoint (#124454)
https://github.com/python/cpython/commit/12eaadc0ad33411bb02945d700b6ed7e758bb188
commit: 12eaadc0ad33411bb02945d700b6ed7e758bb188
branch: main
author: Tian Gao
committer: gaogaotiantian
date: 2024-10-15T15:56:33-04:00
summary:
gh-58956: Set f_trace on frames with breakpoints after setting a new breakpoint
(#124454)
files:
A Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst
M Lib/bdb.py
M Lib/test/test_pdb.py
diff --git a/Lib/bdb.py b/Lib/bdb.py
index 9755d61dd2696c..81bba8a130f97c 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -461,6 +461,14 @@ def set_break(self, filename, lineno, temporary=False,
cond=None,
return 'Line %s:%d does not exist' % (filename, lineno)
self._add_to_breaks(filename, lineno)
bp = Breakpoint(filename, lineno, temporary, cond, funcname)
+# After we set a new breakpoint, we need to search through all frames
+# and set f_trace to trace_dispatch if there could be a breakpoint in
+# that frame.
+frame = self.enterframe
+while frame:
+if self.break_anywhere(frame):
+frame.f_trace = self.trace_dispatch
+frame = frame.f_back
return None
def _load_breaks(self):
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 456effc010954a..8136c591a33001 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -3396,6 +3396,36 @@ def test_issue26053(self):
self.assertRegex(res, "Restarting .* with arguments:\na b c")
self.assertRegex(res, "Restarting .* with arguments:\nd e f")
+def test_issue58956(self):
+# Set a breakpoint in a function that already exists on the call stack
+# should enable the trace function for the frame.
+script = """
+import bar
+def foo():
+ret = bar.bar()
+pass
+foo()
+"""
+commands = """
+b bar.bar
+c
+b main.py:5
+c
+p ret
+quit
+"""
+bar = """
+def bar():
+return 42
+"""
+with open('bar.py', 'w') as f:
+f.write(textwrap.dedent(bar))
+self.addCleanup(os_helper.unlink, 'bar.py')
+stdout, stderr = self.run_pdb_script(script, commands)
+lines = stdout.splitlines()
+self.assertIn('-> pass', lines)
+self.assertIn('(Pdb) 42', lines)
+
def test_step_into_botframe(self):
# gh-125422
# pdb should not be able to step into the botframe (bdb.py)
diff --git
a/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst
b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst
new file mode 100644
index 00..a882a632fddf1b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst
@@ -0,0 +1 @@
+Fixed a bug in :mod:`pdb` where sometimes the breakpoint won't trigger if it
was set on a function which is already in the call stack.
___
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-58956: Set f_trace on frames with breakpoints after setting a new breakpoint (GH-124454) (#125548)
https://github.com/python/cpython/commit/2ded598323ebe44a422d36a6b8ede611b4b34dba commit: 2ded598323ebe44a422d36a6b8ede611b4b34dba branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: gaogaotiantian date: 2024-10-15T20:20:16Z summary: [3.13] gh-58956: Set f_trace on frames with breakpoints after setting a new breakpoint (GH-124454) (#125548) gh-58956: Set f_trace on frames with breakpoints after setting a new breakpoint (GH-124454) (cherry picked from commit 12eaadc0ad33411bb02945d700b6ed7e758bb188) Co-authored-by: Tian Gao files: A Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst M Lib/bdb.py M Lib/test/test_pdb.py diff --git a/Lib/bdb.py b/Lib/bdb.py index a0e46e7f413816..ece0a29fe9f3b1 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -439,6 +439,14 @@ def set_break(self, filename, lineno, temporary=False, cond=None, return 'Line %s:%d does not exist' % (filename, lineno) self._add_to_breaks(filename, lineno) bp = Breakpoint(filename, lineno, temporary, cond, funcname) +# After we set a new breakpoint, we need to search through all frames +# and set f_trace to trace_dispatch if there could be a breakpoint in +# that frame. +frame = self.enterframe +while frame: +if self.break_anywhere(frame): +frame.f_trace = self.trace_dispatch +frame = frame.f_back return None def _load_breaks(self): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 5fe03cc33f34be..d8b9da61d0a308 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3184,6 +3184,36 @@ def test_issue26053(self): self.assertRegex(res, "Restarting .* with arguments:\na b c") self.assertRegex(res, "Restarting .* with arguments:\nd e f") +def test_issue58956(self): +# Set a breakpoint in a function that already exists on the call stack +# should enable the trace function for the frame. +script = """ +import bar +def foo(): +ret = bar.bar() +pass +foo() +""" +commands = """ +b bar.bar +c +b main.py:5 +c +p ret +quit +""" +bar = """ +def bar(): +return 42 +""" +with open('bar.py', 'w') as f: +f.write(textwrap.dedent(bar)) +self.addCleanup(os_helper.unlink, 'bar.py') +stdout, stderr = self.run_pdb_script(script, commands) +lines = stdout.splitlines() +self.assertIn('-> pass', lines) +self.assertIn('(Pdb) 42', lines) + def test_step_into_botframe(self): # gh-125422 # pdb should not be able to step into the botframe (bdb.py) diff --git a/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst new file mode 100644 index 00..a882a632fddf1b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst @@ -0,0 +1 @@ +Fixed a bug in :mod:`pdb` where sometimes the breakpoint won't trigger if it was set on a function which is already in the call stack. ___ 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] Issue template: Remove 3.8 and add 3.14 version (#125552)
https://github.com/python/cpython/commit/fee8fe5858c05599efb014bf4538ef8d52baa45c commit: fee8fe5858c05599efb014bf4538ef8d52baa45c branch: main author: Kirill Podoprigora committer: hugovk <[email protected]> date: 2024-10-16T00:25:20+03:00 summary: Issue template: Remove 3.8 and add 3.14 version (#125552) files: M .github/ISSUE_TEMPLATE/bug.yml diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 395516f29b037c..7b7810cf6965fd 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -34,12 +34,12 @@ body: label: "CPython versions tested on:" multiple: true options: -- "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" +- "3.14" - "CPython main branch" validations: required: true ___ 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]
