Skip to content

Commit 1c291f1

Browse files
committed
Merge branch 'main' into tier-2-tos-caching
2 parents 2850d72 + c825b5d commit 1c291f1

40 files changed

+613
-342
lines changed

.github/CODEOWNERS

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ Python/flowgraph.c @markshannon @iritkatriel
4545
Python/instruction_sequence.c @iritkatriel
4646
Python/bytecodes.c @markshannon
4747
Python/optimizer*.c @markshannon
48-
Python/optimizer_analysis.c @Fidget-Spinner
49-
Python/optimizer_bytecodes.c @Fidget-Spinner
48+
Python/optimizer_analysis.c @Fidget-Spinner @tomasr8
49+
Python/optimizer_bytecodes.c @Fidget-Spinner @tomasr8
50+
Python/optimizer_symbols.c @tomasr8
5051
Python/symtable.c @JelleZijlstra @carljm
5152
Lib/_pyrepl/* @pablogsal @lysnikolaou @ambv
5253
Lib/test/test_patma.py @brandtbucher
@@ -188,13 +189,13 @@ Include/internal/pycore_time.h @pganssle @abalkin
188189
/Tools/cases_generator/ @markshannon
189190

190191
# AST
191-
Python/ast.c @isidentical @JelleZijlstra @eclips4
192-
Python/ast_preprocess.c @isidentical @eclips4
193-
Parser/asdl.py @isidentical @JelleZijlstra @eclips4
194-
Parser/asdl_c.py @isidentical @JelleZijlstra @eclips4
195-
Lib/ast.py @isidentical @JelleZijlstra @eclips4
196-
Lib/_ast_unparse.py @isidentical @JelleZijlstra @eclips4
197-
Lib/test/test_ast/ @eclips4
192+
Python/ast.c @isidentical @JelleZijlstra @eclips4 @tomasr8
193+
Python/ast_preprocess.c @isidentical @eclips4 @tomasr8
194+
Parser/asdl.py @isidentical @JelleZijlstra @eclips4 @tomasr8
195+
Parser/asdl_c.py @isidentical @JelleZijlstra @eclips4 @tomasr8
196+
Lib/ast.py @isidentical @JelleZijlstra @eclips4 @tomasr8
197+
Lib/_ast_unparse.py @isidentical @JelleZijlstra @eclips4 @tomasr8
198+
Lib/test/test_ast/ @eclips4 @tomasr8
198199

199200
# Mock
200201
/Lib/unittest/mock.py @cjw296
@@ -341,3 +342,6 @@ Modules/_xxtestfuzz/ @ammaraskar
341342
Python/remote_debug.h @pablogsal
342343
Python/remote_debugging.c @pablogsal
343344
Modules/_remote_debugging_module.c @pablogsal @ambv @1st1
345+
346+
# gettext
347+
**/*gettext* @tomasr8

Doc/howto/regex.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,9 @@ extension. This regular expression matches ``foo.bar`` and
10161016
Now, consider complicating the problem a bit; what if you want to match
10171017
filenames where the extension is not ``bat``? Some incorrect attempts:
10181018

1019-
``.*[.][^b].*$`` The first attempt above tries to exclude ``bat`` by requiring
1019+
``.*[.][^b].*$``
1020+
1021+
The first attempt above tries to exclude ``bat`` by requiring
10201022
that the first character of the extension is not a ``b``. This is wrong,
10211023
because the pattern also doesn't match ``foo.bar``.
10221024

@@ -1043,7 +1045,9 @@ confusing.
10431045

10441046
A negative lookahead cuts through all this confusion:
10451047

1046-
``.*[.](?!bat$)[^.]*$`` The negative lookahead means: if the expression ``bat``
1048+
``.*[.](?!bat$)[^.]*$``
1049+
1050+
The negative lookahead means: if the expression ``bat``
10471051
doesn't match at this point, try the rest of the pattern; if ``bat$`` does
10481052
match, the whole pattern will fail. The trailing ``$`` is required to ensure
10491053
that something like ``sample.batch``, where the extension only starts with

Doc/library/pkgutil.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ support.
6969

7070
Yield :term:`finder` objects for the given module name.
7171

72-
If fullname contains a ``'.'``, the finders will be for the package
73-
containing fullname, otherwise they will be all registered top level
72+
If *fullname* contains a ``'.'``, the finders will be for the package
73+
containing *fullname*, otherwise they will be all registered top level
7474
finders (i.e. those on both :data:`sys.meta_path` and :data:`sys.path_hooks`).
7575

7676
If the named module is in a package, that package is imported as a side

Doc/library/sys.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,12 +1933,21 @@ always available. Unless explicitly noted otherwise, all variables are read-only
19331933
interpreter is pre-release (alpha, beta, or release candidate) then the
19341934
local and remote interpreters must be the same exact version.
19351935

1936-
.. audit-event:: remote_debugger_script script_path
1936+
.. audit-event:: sys.remote_exec pid script_path
1937+
1938+
When the code is executed in the remote process, an
1939+
:ref:`auditing event <auditing>` ``sys.remote_exec`` is raised with
1940+
the *pid* and the path to the script file.
1941+
This event is raised in the process that called :func:`sys.remote_exec`.
1942+
1943+
.. audit-event:: cpython.remote_debugger_script script_path
19371944

19381945
When the script is executed in the remote process, an
19391946
:ref:`auditing event <auditing>`
1940-
``sys.remote_debugger_script`` is raised
1947+
``cpython.remote_debugger_script`` is raised
19411948
with the path in the remote process.
1949+
This event is raised in the remote process, not the one
1950+
that called :func:`sys.remote_exec`.
19421951

19431952
.. availability:: Unix, Windows.
19441953
.. versionadded:: 3.14

Doc/library/uuid.rst

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,43 +193,52 @@ The :mod:`uuid` module defines the following functions:
193193

194194
.. function:: uuid1(node=None, clock_seq=None)
195195

196-
Generate a UUID from a host ID, sequence number, and the current time. If *node*
197-
is not given, :func:`getnode` is used to obtain the hardware address. If
198-
*clock_seq* is given, it is used as the sequence number; otherwise a random
199-
14-bit sequence number is chosen.
196+
Generate a UUID from a host ID, sequence number, and the current time
197+
according to :rfc:`RFC 9562, §5.1 <9562#section-5.1>`.
198+
199+
When *node* is not specified, :func:`getnode` is used to obtain the hardware
200+
address as a 48-bit positive integer. When a sequence number *clock_seq* is
201+
not specified, a pseudo-random 14-bit positive integer is generated.
202+
203+
If *node* or *clock_seq* exceed their expected bit count,
204+
only their least significant bits are kept.
200205

201206

202207
.. function:: uuid3(namespace, name)
203208

204209
Generate a UUID based on the MD5 hash of a namespace identifier (which is a
205210
UUID) and a name (which is a :class:`bytes` object or a string
206-
that will be encoded using UTF-8).
211+
that will be encoded using UTF-8)
212+
according to :rfc:`RFC 9562, §5.3 <9562#section-5.3>`.
207213

208214

209215
.. function:: uuid4()
210216

211-
Generate a random UUID.
217+
Generate a random UUID in a cryptographically-secure method
218+
according to :rfc:`RFC 9562, §5.4 <9562#section-5.4>`.
212219

213220

214221
.. function:: uuid5(namespace, name)
215222

216223
Generate a UUID based on the SHA-1 hash of a namespace identifier (which is a
217224
UUID) and a name (which is a :class:`bytes` object or a string
218-
that will be encoded using UTF-8).
225+
that will be encoded using UTF-8)
226+
according to :rfc:`RFC 9562, §5.5 <9562#section-5.5>`.
219227

220228

221229
.. function:: uuid6(node=None, clock_seq=None)
222230

223231
Generate a UUID from a sequence number and the current time according to
224-
:rfc:`9562`.
232+
:rfc:`RFC 9562, §5.6 <9562#section-5.6>`.
233+
225234
This is an alternative to :func:`uuid1` to improve database locality.
226235

227236
When *node* is not specified, :func:`getnode` is used to obtain the hardware
228237
address as a 48-bit positive integer. When a sequence number *clock_seq* is
229238
not specified, a pseudo-random 14-bit positive integer is generated.
230239

231-
If *node* or *clock_seq* exceed their expected bit count, only their least
232-
significant bits are kept.
240+
If *node* or *clock_seq* exceed their expected bit count,
241+
only their least significant bits are kept.
233242

234243
.. versionadded:: 3.14
235244

Doc/library/zoneinfo.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ The ``ZoneInfo`` class
195195

196196
The ``ZoneInfo`` class has two alternate constructors:
197197

198-
.. classmethod:: ZoneInfo.from_file(fobj, /, key=None)
198+
.. classmethod:: ZoneInfo.from_file(file_obj, /, key=None)
199199

200200
Constructs a ``ZoneInfo`` object from a file-like object returning bytes
201201
(e.g. a file opened in binary mode or an :class:`io.BytesIO` object).
@@ -325,7 +325,7 @@ The behavior of a ``ZoneInfo`` file depends on how it was constructed:
325325
>>> a is b
326326
False
327327
328-
3. ``ZoneInfo.from_file(fobj, /, key=None)``: When constructed from a file, the
328+
3. ``ZoneInfo.from_file(file_obj, /, key=None)``: When constructed from a file, the
329329
``ZoneInfo`` object raises an exception on pickling. If an end user wants to
330330
pickle a ``ZoneInfo`` constructed from a file, it is recommended that they
331331
use a wrapper type or a custom serialization function: either serializing by

Include/cpython/longintrepr.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,6 @@ _PyLong_IsCompact(const PyLongObject* op) {
124124
return op->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS);
125125
}
126126

127-
static inline int
128-
PyLong_CheckCompact(const PyObject *op)
129-
{
130-
return PyLong_CheckExact(op) && _PyLong_IsCompact((PyLongObject *)op);
131-
}
132-
133127
#define PyUnstable_Long_IsCompact _PyLong_IsCompact
134128

135129
static inline Py_ssize_t

Include/internal/pycore_long.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,12 @@ _PyLong_FlipSign(PyLongObject *op) {
312312
#define _PyLong_FALSE_TAG TAG_FROM_SIGN_AND_SIZE(0, 0)
313313
#define _PyLong_TRUE_TAG TAG_FROM_SIGN_AND_SIZE(1, 1)
314314

315+
static inline int
316+
_PyLong_CheckExactAndCompact(PyObject *op)
317+
{
318+
return PyLong_CheckExact(op) && _PyLong_IsCompact((const PyLongObject *)op);
319+
}
320+
315321
#ifdef __cplusplus
316322
}
317323
#endif

Lib/sqlite3/__main__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,21 @@ def runsource(self, source, filename="<input>", symbol="single"):
6363
if source[0] == ".":
6464
match source[1:].strip():
6565
case "version":
66-
print(f"{sqlite3.sqlite_version}")
66+
print(sqlite3.sqlite_version)
6767
case "help":
68-
print("Enter SQL code and press enter.")
68+
t = theme.syntax
69+
print(f"Enter SQL code or one of the below commands, and press enter.\n\n"
70+
f"{t.builtin}.version{t.reset} Print underlying SQLite library version\n"
71+
f"{t.builtin}.help{t.reset} Print this help message\n"
72+
f"{t.builtin}.quit{t.reset} Exit the CLI, equivalent to CTRL-D\n")
6973
case "quit":
7074
sys.exit(0)
7175
case "":
7276
pass
7377
case _ as unknown:
7478
t = theme.traceback
75-
self.write(f'{t.type}Error{t.reset}:{t.message} unknown'
76-
f'command or invalid arguments: "{unknown}".\n{t.reset}')
79+
self.write(f'{t.type}Error{t.reset}: {t.message}unknown '
80+
f'command: "{unknown}"{t.reset}\n')
7781
else:
7882
if not sqlite3.complete_statement(source):
7983
return True

Lib/test/audit-tests.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,34 @@ def test_assert_unicode():
643643
else:
644644
raise RuntimeError("Expected sys.audit(9) to fail.")
645645

646+
def test_sys_remote_exec():
647+
import tempfile
648+
649+
pid = os.getpid()
650+
event_pid = -1
651+
event_script_path = ""
652+
remote_event_script_path = ""
653+
def hook(event, args):
654+
if event not in ["sys.remote_exec", "cpython.remote_debugger_script"]:
655+
return
656+
print(event, args)
657+
match event:
658+
case "sys.remote_exec":
659+
nonlocal event_pid, event_script_path
660+
event_pid = args[0]
661+
event_script_path = args[1]
662+
case "cpython.remote_debugger_script":
663+
nonlocal remote_event_script_path
664+
remote_event_script_path = args[0]
665+
666+
sys.addaudithook(hook)
667+
with tempfile.NamedTemporaryFile(mode='w+', delete=True) as tmp_file:
668+
tmp_file.write("a = 1+1\n")
669+
tmp_file.flush()
670+
sys.remote_exec(pid, tmp_file.name)
671+
assertEqual(event_pid, pid)
672+
assertEqual(event_script_path, tmp_file.name)
673+
assertEqual(remote_event_script_path, tmp_file.name)
646674

647675
if __name__ == "__main__":
648676
from test.support import suppress_msvcrt_asserts

Lib/test/support/__init__.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
# sys
4747
"MS_WINDOWS", "is_jython", "is_android", "is_emscripten", "is_wasi",
4848
"is_apple_mobile", "check_impl_detail", "unix_shell", "setswitchinterval",
49+
"support_remote_exec_only",
4950
# os
5051
"get_pagesize",
5152
# network
@@ -3069,6 +3070,27 @@ def is_libssl_fips_mode():
30693070
return False # more of a maybe, unless we add this to the _ssl module.
30703071
return get_fips_mode() != 0
30713072

3073+
def _supports_remote_attaching():
3074+
PROCESS_VM_READV_SUPPORTED = False
3075+
3076+
try:
3077+
from _remote_debugging import PROCESS_VM_READV_SUPPORTED
3078+
except ImportError:
3079+
pass
3080+
3081+
return PROCESS_VM_READV_SUPPORTED
3082+
3083+
def _support_remote_exec_only_impl():
3084+
if not sys.is_remote_debug_enabled():
3085+
return unittest.skip("Remote debugging is not enabled")
3086+
if sys.platform not in ("darwin", "linux", "win32"):
3087+
return unittest.skip("Test only runs on Linux, Windows and macOS")
3088+
if sys.platform == "linux" and not _supports_remote_attaching():
3089+
return unittest.skip("Test only runs on Linux with process_vm_readv support")
3090+
return _id
3091+
3092+
def support_remote_exec_only(test):
3093+
return _support_remote_exec_only_impl()(test)
30723094

30733095
class EqualToForwardRef:
30743096
"""Helper to ease use of annotationlib.ForwardRef in tests.

Lib/test/test_audit.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,14 @@ def test_assert_unicode(self):
322322
if returncode:
323323
self.fail(stderr)
324324

325+
@support.support_remote_exec_only
326+
@support.cpython_only
327+
def test_sys_remote_exec(self):
328+
returncode, events, stderr = self.run_python("test_sys_remote_exec")
329+
self.assertTrue(any(["sys.remote_exec" in event for event in events]))
330+
self.assertTrue(any(["cpython.remote_debugger_script" in event for event in events]))
331+
if returncode:
332+
self.fail(stderr)
325333

326334
if __name__ == "__main__":
327335
unittest.main()

Lib/test/test_capi/test_opt.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,36 @@ def testfunc(n):
23192319
self.assertNotIn("_GUARD_TOS_INT", uops)
23202320
self.assertNotIn("_GUARD_NOS_INT", uops)
23212321

2322+
def test_attr_promotion_failure(self):
2323+
# We're not testing for any specific uops here, just
2324+
# testing it doesn't crash.
2325+
script_helper.assert_python_ok('-c', textwrap.dedent("""
2326+
import _testinternalcapi
2327+
import _opcode
2328+
import email
2329+
2330+
def get_first_executor(func):
2331+
code = func.__code__
2332+
co_code = code.co_code
2333+
for i in range(0, len(co_code), 2):
2334+
try:
2335+
return _opcode.get_executor(code, i)
2336+
except ValueError:
2337+
pass
2338+
return None
2339+
2340+
def testfunc(n):
2341+
for _ in range(n):
2342+
email.jit_testing = None
2343+
prompt = email.jit_testing
2344+
del email.jit_testing
2345+
2346+
2347+
testfunc(_testinternalcapi.TIER2_THRESHOLD)
2348+
ex = get_first_executor(testfunc)
2349+
assert ex is not None
2350+
"""))
2351+
23222352

23232353
def global_identity(x):
23242354
return x

Lib/test/test_exceptions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,7 @@ def foo():
14451445
foo()
14461446
support.gc_collect()
14471447

1448+
@support.skip_emscripten_stack_overflow()
14481449
@cpython_only
14491450
def test_recursion_normalizing_exception(self):
14501451
import_module("_testinternalcapi")
@@ -1522,6 +1523,7 @@ def test_recursion_normalizing_infinite_exception(self):
15221523
self.assertIn(b'Done.', out)
15231524

15241525

1526+
@support.skip_emscripten_stack_overflow()
15251527
def test_recursion_in_except_handler(self):
15261528

15271529
def set_relative_recursion_limit(n):

Lib/test/test_sqlite3/test_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def test_interact_dot_commands_unknown(self):
138138
self.assertEndsWith(out, self.PS1)
139139
self.assertEqual(out.count(self.PS1), 2)
140140
self.assertEqual(out.count(self.PS2), 0)
141-
self.assertIn("Error", err)
141+
self.assertIn('Error: unknown command: "', err)
142142
# test "unknown_command" is pointed out in the error message
143143
self.assertIn("unknown_command", err)
144144

0 commit comments

Comments
 (0)