8000 Merge branch 'main' into main · python/cpython@b90e980 · GitHub
[go: up one dir, main page]

Skip to content

Commit b90e980

Browse files
authored
Merge branch 'main' into main
2 parents d0fe4a6 + ee36db5 commit b90e980

File tree

67 files changed

+950
-446
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+950
-446
lines changed

Doc/c-api/gcsupport.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ provided. In order to use this macro, the :c:member:`~PyTypeObject.tp_traverse`
180180
must name its arguments exactly *visit* and *arg*:
181181
182182
183-
.. c:function:: void Py_VISIT(PyObject *o)
183+
.. c:macro:: Py_VISIT(o)
184184
185-
If *o* is not ``NULL``, call the *visit* callback, with arguments *o*
185+
If the :c:expr:`PyObject *` *o* is not ``NULL``, call the *visit* callback, with arguments *o*
186186
and *arg*. If *visit* returns a non-zero value, then return it.
187187
Using this macro, :c:member:`~PyTypeObject.tp_traverse` handlers
188188
look like::

Doc/faq/design.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,12 @@ strings representing the files in the current directory. Functions which
420420
operate on this output would generally not break if you added another file or
421421
two to the directory.
422422

423-
Tuples are immutable, meaning that once a tuple has been created, you can't
424-
replace any of its elements with a new value. Lists are mutable, meaning that
425-
you can always change a list's elements. Only immutable elements can be used as
426-
dictionary keys, and hence only tuples and not lists can be used as keys.
423+
Tuples are :term:`immutable`, meaning that once a tuple has been created, you can't
424+
replace any of its elements with a new value. Lists are :term:`mutable`, meaning that
425+
you can always change a list's elements. Only :term:`hashable` objects can
426+
be used as dictionary keys. Most immutable types are hashable, which is why
427+
tuples, but not lists, can be used as keys. Note, however, that a tuple is
428+
only hashable if all of its elements are hashable.
427429

428430

429431
How are lists implemented in CPython?

Doc/howto/free-threading-extensions.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ You can use it to enable code that only runs under the free-threaded build::
2323
/* code that only runs in the free-threaded build */
2424
#endif
2525

26+
.. note::
27+
28+
On Windows, this macro is not defined automatically, but must be specified
29+
to the compiler when building. The :func:`sysconfig.get_config_var` function
30+
can be used to determine whether the current running interpreter had the
31+
macro defined.
32+
33+
2634
Module Initialization
2735
=====================
2836

Doc/howto/functional.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,8 @@ have the form::
372372
for expr2 in sequence2
373373
if condition2
374374
for expr3 in sequence3
375-
...
376375
if condition3
376+
...
377377
for exprN in sequenceN
378378
if conditionN )
379379

Doc/library/json.rst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@ is a lightweight data interchange format inspired by
1818
`JavaScript <https://en.wikipedia.org/wiki/JavaScript>`_ object literal syntax
1919
(although it is not a strict subset of JavaScript [#rfc-errata]_ ).
2020

21+
.. note::
22+
The term "object" in the context of JSON processing in Python can be
23+
ambiguous. All values in Python are objects. In JSON, an object refers to
24+
any data wrapped in curly braces, similar to a Python dictionary.
25+
2126
.. warning::
2227
Be cautious when parsing JSON data from untrusted sources. A malicious
2328
JSON string may cause the decoder to consume considerable CPU and memory
2429
resources. Limiting the size of data to be parsed is recommended.
2530

26-
:mod:`json` exposes an API familiar to users of the standard library
31+
This module exposes an API familiar to users of the standard library
2732
:mod:`marshal` and :mod:`pickle` modules.
2833

2934
Encoding basic Python object hierarchies::
@@ -60,7 +65,7 @@ Pretty printing::
6065
"6": 7
6166
}
6267

63-
Specializing JSON object encoding::
68+
Customizing JSON object encoding::
6469

6570
>>> import json
6671
>>> def custom_json(obj):
@@ -83,7 +88,7 @@ Decoding JSON::
8388
>>> json.load(io)
8489
['streaming API']
8590

86-
Specializing JSON object decoding::
91+
Customizing JSON object decoding::
8792

8893
>>> import json
8994
>>> def as_complex(dct):
@@ -279,7 +284,7 @@ Basic Usage
279284

280285
:param object_hook:
281286
If set, a function that is called with the result of
282-
any object literal decoded (a :class:`dict`).
287+
any JSON object literal decoded (a :class:`dict`).
283288
The return value of this function will be used
284289
instead of the :class:`dict`.
285290
This feature can be used to implement custom decoders,
@@ -289,7 +294,7 @@ Basic Usage
289294

290295
:param object_pairs_hook:
291296
If set, a function that is called with the result of
292-
any object literal decoded with an ordered list of pairs.
297+
any JSON object literal decoded with an ordered list of pairs.
293298
The return value of this function will be used
294299
instead of the :class:`dict`.
295300
This feature can be used to implement custom decoders.

Doc/library/re.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,8 @@ Functions
991991
That way, separator components are always found at the same relative
992992
indices within the result list.
993993

994-
Empty matches for the pattern split the string only when not adjacent
995-
to a previous empty match.
994+
Adjacent empty matches are not possible, but an empty match can occur
995+
immediately after a non-empty match.
996996

997997
.. code:: pycon
998998
@@ -1095,9 +1095,12 @@ Functions
10951095

10961096
The optional argument *count* is the maximum number of pattern occurrences to be
10971097
replaced; *count* must be a non-negative integer. If omitted or zero, all
1098-
occurrences will be replaced. Empty matches for the pattern are replaced only
1099-
when not adjacent to a previous empty match, so ``sub('x*', '-', 'abxd')`` returns
1100-
``'-a-b--d-'``.
1098+
occurrences will be replaced.
1099+
1100+
Adjacent empty matches are not possible, but an empty match can occur
1101+
immediately after a non-empty match.
1102+
As a result, ``sub('x*', '-', 'abxd')`` returns ``'-a-b--d-'``
1103+
instead of ``'-a-b-d-'``.
11011104

11021105
.. index:: single: \g; in regular expressions
11031106

@@ -1128,8 +1131,7 @@ Functions
11281131
.. versionchanged:: 3.7
11291132
Unknown escapes in *repl* consisting of ``'\'`` and an ASCII letter
11301133
now are errors.
1131-
Empty matches for the pattern are replaced when adjacent to a previous
1132-
non-empty match.
1134+
An empty match can occur immediately after a non-empty match.
11331135

11341136
.. versionchanged:: 3.12
11351137
Group *id* can only contain ASCII digits.

Doc/tutorial/controlflow.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ Here is an example of a multi-line docstring::
10561056
>>> print(my_function.__doc__)
10571057
Do nothing, but document it.
10581058

1059-
No, really, it doesn't do anything.
1059+
No, really, it doesn't do anything.
10601060

10611061

10621062
.. _tut-annotations:

Doc/whatsnew/3.10.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -551,11 +551,12 @@ Patterns and classes
551551
552552
If you are using classes to structure your data, you can use as a pattern
553553
the class name followed by an argument list resembling a constructor. This
554-
pattern has the ability to capture class attributes into variables::
554+
pattern has the ability CDA2 to capture instance attributes into variables::
555555
556556
class Point:
557-
x: int
558-
y: int
557+
def __init__(self, x, y):
558+
self.x = x
559+
self.y = y
559560
560561
def location(point):
561562
match point:

Doc/whatsnew/3.14.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,12 @@ Kumar Aditya, Edgar Margffoy, and many others.
829829
Some of these contributors are employed by Meta, which has continued to provide
830830
significant engineering resources to support this project.
831831

832+
From 3.14, when compiling extension modules for the free-threaded build of
833+
CPython on Windows, the preprocessor variable ``Py_GIL_DISABLED`` now needs to
834+
be specified by the build backend, as it will no longer be determined
835+
automatically by the C compiler. For a running interpreter, the setting that
836+
was used at compile time can be found using :func:`sysconfig.get_config_var`.
837+
832838

833839
.. _whatsnew314-pyrepl-highlighting:
834840

Doc/whatsnew/3.15.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@ sysconfig
145145
(Contributed by Filipe Laíns in :gh:`92897`.)
146146

147147

148+
threading
149+
---------
150+
151+
* Remove support for arbitrary positional or keyword arguments in the C
152+
implementation of :class:`~threading.RLock` objects. This was deprecated
153+
in Python 3.14.
154+
(Contributed by Bénédikt Tran in :gh:`134087`.)
155+
156+
148157
typing
149158
------
150159

Grammar/python.gram

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,15 +1418,15 @@ invalid_except_stmt:
14181418
RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
14191419
| a='except' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
14201420
| a='except' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
1421-
| 'except' expression 'as' a=expression {
1421+
| 'except' expression 'as' a=expression ':' block {
14221422
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
14231423
a, "cannot use except statement with %s", _PyPegen_get_expr_name(a)) }
14241424
invalid_except_star_stmt:
14251425
| 'except' '*' a=expression ',' expressions 'as' NAME ':' {
14261426
RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
14271427
| a='except' '*' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
14281428
| a='except' '*' (NEWLINE | ':') { RAISE_SYNTAX_ERROR("expected one or more exception types") }
1429-
| 'except' '*' expression 'as' a=expression {
1429+
| 'except' '*' expression 'as' a=expression ':' block {
14301430
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
14311431
a, "cannot use except* statement with %s", _PyPegen_get_expr_name(a)) }
14321432
invalid_finally_stmt:

Include/Python.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@
5959
# include <intrin.h> // __readgsqword()
6060
#endif
6161

62+
// Suppress known warnings in Python header files.
63+
#if defined(_MSC_VER)
64+
// Warning that alignas behaviour has changed. Doesn't affect us, because we
65+
// never relied on the old behaviour.
66+
#pragma warning(push)
67+
#pragma warning(disable: 5274)
68+
#endif
69+
6270
// Include Python header files
6371
#include "pyport.h"
6472
#include "pymacro.h"
@@ -138,4 +146,9 @@
138146
#include "cpython/pyfpe.h"
139147
#include "cpython/tracemalloc.h"
140148

149+
// Restore warning filter
150+
#ifdef _MSC_VER
151+
#pragma warning(pop)
152+
#endif
153+
141154
#endif /* !Py_PYTHON_H */

Include/py_curses.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ static void **PyCurses_API;
109109
static const char catchall_ERR[] = "curses function returned ERR";
110110
static const char catchall_NULL[] = "curses function returned NULL";
111111

112+
#if defined(CURSES_MODULE) || defined(CURSES_PANEL_MODULE)
113+
/* Error messages shared by the curses package */
114+
# define CURSES_ERROR_FORMAT "%s() returned %s"
115+
# define CURSES_ERROR_VERBOSE_FORMAT "%s() (called by %s()) returned %s"
116+
# define CURSES_ERROR_MUST_CALL_FORMAT "must call %s() first"
117+
#endif
118+
112119
#ifdef __cplusplus
113120
}
114121
#endif

InternalDocs/generators.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ interpreter state.
2828

2929
The `frame` of a generator is embedded in the generator object struct as a
3030
[`_PyInterpreterFrame`](frames.md) (see `_PyGenObject_HEAD` in
31-
[`pycore_genobject.h`](../Include/internal/pycore_genobject.h)).
31+
[`pycore_interpframe_structs.h`](../Include/internal/pycore_interpframe_structs.h)).
3232
This means that we can get the frame from the generator or the generator
33-
from the frame (see `_PyGen_GetGeneratorFromFrame` in the same file).
33+
from the frame (see `_PyGen_GetGeneratorFromFrame` in [`pycore_genobject.h`](../Include/internal/pycore_genobject.h)).
3434
Other fields of the generator struct include metadata (such as the name of
3535
the generator function) and runtime state information (such as whether its
3636
frame is executing, suspended, cleared, etc.).

Lib/_pyrepl/simple_interact.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ def run_multiline_interactive_console(
110110
more_lines = functools.partial(_more_lines, console)
111111
input_n = 0
112112

113+
_is_x_showrefcount_set = sys._xoptions.get("showrefcount")
114+
_is_pydebug_build = hasattr(sys, "gettotalrefcount")
115+
show_ref_count = _is_x_showrefcount_set and _is_pydebug_build
116+
113117
def maybe_run_command(statement: str) -> bool:
114118
statement = statement.strip()
115119
if statement in console.locals or statement not in REPL_COMMANDS:
@@ -167,3 +171,8 @@ def maybe_run_command(statement: str) -> bool:
167171
except:
168172
console.showtraceback()
169173
console.resetbuffer()
174+
if show_ref_count:
175+
console.write(
176+
f"[{sys.gettotalrefcount()} refs,"
177+
f" {sys.getallocatedblocks()} blocks]\n"
178+
)

Lib/asyncio/futures.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -351,22 +351,19 @@ def _set_concurrent_future_state(concurrent, source):
351351
def _copy_future_state(source, dest):
352352
"""Internal helper to copy state from another Future.
353353
354-
The other Future may be a concurrent.futures.Future.
354+
The other Future must be a concurrent.futures.Future.
355355
"""
356-
assert source.done()
357356
if dest.cancelled():
358357
return
359358
assert not dest.done()
360-
if source.cancelled():
359+
done, cancelled, result, exception = source._get_snapshot()
360+
assert done
361+
if cancelled:
361362
dest.cancel()
363+
elif exception is not None:
364+
dest.set_exception(_convert_future_exc(exception))
362365
else:
363-
exception = source.exception()
364-
if exception is not None:
365-
dest.set_exception(_convert_future_exc(exception))
366-
else:
367-
result = source.result()
368-
dest.set_result(result)
369-
366+
dest.set_result(result)
370367

371368
def _chain_future(source, destination):
372369
"""Chain two futures so that when one completes, so does the other.

Lib/concurrent/futures/_base.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,33 @@ def set_exception(self, exception):
558558
self._condition.notify_all()
559559
self._invoke_callbacks()
560560

561+
def _get_snapshot(self):
562+
"""Get a snapshot of the future's current state.
563+
564+
This method atomically retrieves the state in one lock acquisition,
565+
which is significantly faster than multiple method calls.
566+
567+
Returns:
568+
Tuple of (done, cancelled, result, exception)
569+
- done: True if the future is done (cancelled or finished)
570+
- cancelled: True if the future was cancelled
571+
- result: The result if available and not cancelled
572+
- exception: The exception if available and not cancelled
573+
"""
574+
# Fast path: check if already finished without lock
575+
if self._state == FINISHED:
576+
return True, False, self._result, self._exception
577+
578+
# Need lock for other states since they can change
579+
with self._condition:
580+
# We have to check the state again after acquiring the lock
581+
# because it may have changed in the meantime.
582+
if self._state == FINISHED:
583+
return True, False, self._result, self._exception
584+
if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED}:
585+
return True, True, None, None
586+
return False, False, None, None
587+
561588
__class_getitem__ = classmethod(types.GenericAlias)
562589

563590
class Executor(object):

Lib/http/server.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,11 +818,14 @@ def list_directory(self, path):
818818
return None
819819
list.sort(key=lambda a: a.lower())
820820
r = []
821+
displaypath = self.path
822+
displaypath = displaypath.split('#', 1)[0]
823+
displaypath = displaypath.split('?', 1)[0]
821824
try:
822-
displaypath = urllib.parse.unquote(self.path,
825+
displaypat 73AA h = urllib.parse.unquote(displaypath,
823826
errors='surrogatepass')
824827
except UnicodeDecodeError:
825-
displaypath = urllib.parse.unquote(self.path)
828+
displaypath = urllib.parse.unquote(displaypath)
826829
displaypath = html.escape(displaypath, quote=False)
827830
enc = sys.getfilesystemencoding()
828831
title = f'Directory listing for {displaypath}'

Lib/ntpath.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,10 @@ def _getfinalpathname_nonstrict(path):
661661
# 87: ERROR_INVALID_PARAMETER
662662
# 123: ERROR_INVALID_NAME
663663
# 161: ERROR_BAD_PATHNAME
664+
# 1005: ERROR_UNRECOGNIZED_VOLUME
664665
# 1920: ERROR_CANT_ACCESS_FILE
665666
# 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink)
666-
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1920, 1921
667+
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1005, 1920, 1921
667668

668669
# Non-strict algorithm is to find as much of the target directory
669670
# as we can and join the rest.

0 commit comments

Comments
 (0)
0