Skip to content

Commit e29ae88

Browse files
Merge branch 'main' into platform-binaries-jit
2 parents e750eb0 + 0a97941 commit e29ae88

File tree

119 files changed

+2541
-684
lines changed

Some content is hidden

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

119 files changed

+2541
-684
lines changed

Doc/c-api/import.rst

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ Importing Modules
129129
of :class:`~importlib.machinery.SourceFileLoader` otherwise.
130130
131131
The module's :attr:`~module.__file__` attribute will be set to the code
132-
object's :attr:`~codeobject.co_filename`. If applicable,
133-
:attr:`~module.__cached__` will also be set.
132+
object's :attr:`~codeobject.co_filename`.
134133
135134
This function will reload the module if it was already imported. See
136135
:c:func:`PyImport_ReloadModule` for the intended way to reload a module.
@@ -142,10 +141,13 @@ Importing Modules
142141
:c:func:`PyImport_ExecCodeModuleWithPathnames`.
143142
144143
.. versionchanged:: 3.12
145-
The setting of :attr:`~module.__cached__` and :attr:`~module.__loader__`
144+
The setting of ``__cached__`` and :attr:`~module.__loader__`
146145
is deprecated. See :class:`~importlib.machinery.ModuleSpec` for
147146
alternatives.
148147
148+
.. versionchanged:: 3.15
149+
``__cached__`` is no longer set.
150+
149151
150152
.. c:function:: PyObject* PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)
151153
@@ -157,16 +159,19 @@ Importing Modules
157159
158160
.. c:function:: PyObject* PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname)
159161
160-
Like :c:func:`PyImport_ExecCodeModuleEx`, but the :attr:`~module.__cached__`
161-
attribute of the module object is set to *cpathname* if it is
162-
non-``NULL``. Of the three functions, this is the preferred one to use.
162+
Like :c:func:`PyImport_ExecCodeModuleEx`, but the path to any compiled file
163+
via *cpathname* is used appropriately when non-``NULL``. Of the three
164+
functions, this is the preferred one to use.
163165
164166
.. versionadded:: 3.3
165167
166168
.. versionchanged:: 3.12
167-
Setting :attr:`~module.__cached__` is deprecated. See
169+
Setting ``__cached__`` is deprecated. See
168170
:class:`~importlib.machinery.ModuleSpec` for alternatives.
169171
172+
.. versionchanged:: 3.15
173+
``__cached__`` no longer set.
174+
170175
171176
.. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, const char *pathname, const char *cpathname)
172177

Doc/deprecations/c-api-pending-removal-in-3.20.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Pending removal in Python 3.20
22
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33

4+
* :c:func:`!_PyObject_CallMethodId`, :c:func:`!_PyObject_GetAttrId` and
5+
:c:func:`!_PyUnicode_FromId` are deprecated since 3.15 and will be removed in
6+
3.20. Instead, use :c:func:`PyUnicode_FromString()` and cache the result in
7+
the module state, then call :c:func:`PyObject_CallMethod` or
8+
:c:func:`PyObject_GetAttr`.
9+
(Contributed by Victor Stinner in :gh:`141049`.)
10+
411
* The ``cval`` field in :c:type:`PyComplexObject` (:gh:`128813`).
512
Use :c:func:`PyComplex_AsCComplex` and :c:func:`PyComplex_FromCComplex`
613
to convert a Python complex number to/from the C :c:type:`Py_complex`

Doc/deprecations/pending-removal-in-3.15.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ Pending removal in Python 3.15
33

44
* The import system:
55

6-
* Setting :attr:`~module.__cached__` on a module while
6+
* Setting ``__cached__`` on a module while
77
failing to set :attr:`__spec__.cached <importlib.machinery.ModuleSpec.cached>`
8-
is deprecated. In Python 3.15, :attr:`!__cached__` will cease to be set or
8+
is deprecated. In Python 3.15, ``__cached__`` will cease to be set or
99
take into consideration by the import system or standard library. (:gh:`97879`)
1010

1111
* Setting :attr:`~module.__package__` on a module while

Doc/howto/gdb_helpers.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ enabled::
136136
at Objects/unicodeobject.c:551
137137
#7 0x0000000000440d94 in PyUnicodeUCS2_FromString (u=0x5c2b8d "__lltrace__") at Objects/unicodeobject.c:569
138138
#8 0x0000000000584abd in PyDict_GetItemString (v=
139-
{'Yuck': <type at remote 0xad4730>, '__builtins__': <module at remote 0x7ffff7fd5ee8>, '__file__': 'Lib/test/crashers/nasty_eq_vs_dict.py', '__package__': None, 'y': <Yuck(i=0) at remote 0xaacd80>, 'dict': {0: 0, 1: 1, 2: 2, 3: 3}, '__cached__': None, '__name__': '__main__', 'z': <Yuck(i=0) at remote 0xaace60>, '__doc__': None}, key=
139+
{'Yuck': <type at remote 0xad4730>, '__builtins__': <module at remote 0x7ffff7fd5ee8>, '__file__': 'Lib/test/crashers/nasty_eq_vs_dict.py', '__package__': None, 'y': <Yuck(i=0) at remote 0xaacd80>, 'dict': {0: 0, 1: 1, 2: 2, 3: 3}, '__name__': '__main__', 'z': <Yuck(i=0) at remote 0xaace60>, '__doc__': None}, key=
140140
0x5c2b8d "__lltrace__") at Objects/dictobject.c:2171
141141

142142
Notice how the dictionary argument to ``PyDict_GetItemString`` is displayed

Doc/library/argparse.rst

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,27 @@ are set.
645645

646646
.. versionadded:: 3.14
647647

648+
To highlight inline code in your description or epilog text, you can use
649+
backticks::
650+
651+
>>> parser = argparse.ArgumentParser(
652+
... formatter_class=argparse.RawDescriptionHelpFormatter,
653+
... epilog='''Examples:
654+
... `python -m myapp --verbose`
655+
... `python -m myapp --config settings.json`
656+
... ''')
657+
658+
When colors are enabled, the text inside backticks will be displayed in a
659+
distinct color to help examples stand out. When colors are disabled, backticks
660+
are preserved as-is, which is readable in plain text.
661+
662+
.. note::
663+
664+
Backtick markup only applies to description and epilog text. It does not
665+
apply to individual argument ``help`` strings.
666+
667+
.. versionadded:: 3.15
668+
648669

649670
The add_argument() method
650671
-------------------------
@@ -1679,7 +1700,7 @@ The Namespace object
16791700
Other utilities
16801701
---------------
16811702

1682-
Sub-commands
1703+
Subcommands
16831704
^^^^^^^^^^^^
16841705

16851706
.. method:: ArgumentParser.add_subparsers(*, [title], [description], [prog], \
@@ -1708,7 +1729,7 @@ Sub-commands
17081729
* *description* - description for the sub-parser group in help output, by
17091730
default ``None``
17101731

1711-
* *prog* - usage information that will be displayed with sub-command help,
1732+
* *prog* - usage information that will be displayed with subcommand help,
17121733
by default the name of the program and any positional arguments before the
17131734
subparser argument
17141735

@@ -1718,7 +1739,7 @@ Sub-commands
17181739
* action_ - the basic type of action to be taken when this argument is
17191740
encountered at the command line
17201741

1721-
* dest_ - name of the attribute under which sub-command name will be
1742+
* dest_ - name of the attribute under which subcommand name will be
17221743
stored; by default ``None`` and no value is stored
17231744

17241745
* required_ - Whether or not a subcommand must be provided, by default

Doc/library/functions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ are always available. They are listed here in alphabetical order.
526526
>>> dir() # show the names in the module namespace # doctest: +SKIP
527527
['__builtins__', '__name__', 'struct']
528528
>>> dir(struct) # show the names in the struct module # doctest: +SKIP
529-
['Struct', '__all__', '__builtins__', '__cached__', '__doc__', '__file__',
529+
['Struct', '__all__', '__builtins__', '__doc__', '__file__',
530530
'__initializing__', '__loader__', '__name__', '__package__',
531531
'_clearcache', 'calcsize', 'error', 'pack', 'pack_into',
532532
'unpack', 'unpack_from']

Doc/library/importlib.rst

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,12 @@ Functions
210210
:exc:`ModuleNotFoundError` is raised when the module being reloaded lacks
211211
a :class:`~importlib.machinery.ModuleSpec`.
212212

213+
.. versionchanged:: next
214+
If *module* is a lazy module that has not yet been materialized (i.e.,
215+
loaded via :class:`importlib.util.LazyLoader` and not yet accessed),
216+
calling :func:`reload` is a no-op and returns the module unchanged.
217+
This prevents the reload from unintentionally triggering the lazy load.
218+
213219
.. warning::
214220
This function is not thread-safe. Calling it from multiple threads can result
215221
in unexpected behavior. It's recommended to use the :class:`threading.Lock`
@@ -1197,8 +1203,7 @@ find and load modules.
11971203

11981204
.. attribute:: cached
11991205

1200-
The filename of a compiled version of the module's code
1201-
(see :attr:`module.__cached__`).
1206+
The filename of a compiled version of the module's code.
12021207
The :term:`finder` should always set this attribute but it may be ``None``
12031208
for modules that do not need compiled code stored.
12041209

@@ -1300,7 +1305,7 @@ an :term:`importer`.
13001305

13011306
.. versionadded:: 3.4
13021307

1303-
.. function:: cache_from_source(path, debug_override=None, *, optimization=None)
1308+
.. function:: cache_from_source(path, *, optimization=None)
13041309

13051310
Return the :pep:`3147`/:pep:`488` path to the byte-compiled file associated
13061311
with the source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return
@@ -1319,12 +1324,6 @@ an :term:`importer`.
13191324
``/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc``. The string representation
13201325
of *optimization* can only be alphanumeric, else :exc:`ValueError` is raised.
13211326

1322-
The *debug_override* parameter is deprecated and can be used to override
1323-
the system's value for ``__debug__``. A ``True`` value is the equivalent of
1324-
setting *optimization* to the empty string. A ``False`` value is the same as
1325-
setting *optimization* to ``1``. If both *debug_override* an *optimization*
1326-
are not ``None`` then :exc:`TypeError` is raised.
1327-
13281327
.. versionadded:: 3.4
13291328

13301329
.. versionchanged:: 3.5
@@ -1334,6 +1333,9 @@ an :term:`importer`.
13341333
.. versionchanged:: 3.6
13351334
Accepts a :term:`path-like object`.
13361335

1336+
.. versionchanged:: 3.15
1337+
The *debug_override* parameter was removed.
1338+
13371339

13381340
.. function:: source_from_cache(path)
13391341

Doc/library/profiling.sampling.rst

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ production systems. The target process requires no modification and need not
191191
be restarted. The profiler attaches, collects samples for the specified
192192
duration, then detaches and produces output.
193193

194+
::
195+
196+
python -m profiling.sampling attach --live 12345
197+
python -m profiling.sampling attach --flamegraph -d 30 -o profile.html 12345
198+
194199
On most systems, attaching to another process requires appropriate permissions.
195200
See :ref:`profiling-permissions` for platform-specific requirements.
196201

@@ -470,9 +475,10 @@ which you can use to judge whether the data is sufficient for your analysis.
470475
Profiling modes
471476
===============
472477

473-
The sampling profiler supports three modes that control which samples are
478+
The sampling profiler supports four modes that control which samples are
474479
recorded. The mode determines what the profile measures: total elapsed time,
475-
CPU execution time, or time spent holding the global interpreter lock.
480+
CPU execution time, time spent holding the global interpreter lock, or
481+
exception handling.
476482

477483

478484
Wall-clock mode
@@ -528,6 +534,25 @@ I/O-bound or waiting. The function spends most of its time waiting for network,
528534
disk, locks, or sleep. CPU optimization won't help here; consider async I/O,
529535
connection pooling, or reducing wait time instead.
530536

537+
.. code-block:: python
538+
539+
import time
540+
541+
def do_sleep():
542+
time.sleep(2)
543+
544+
def do_compute():
545+
sum(i**2 for i in range(1000000))
546+
547+
if __name__ == "__main__":
548+
do_sleep()
549+
do_compute()
550+
551+
::
552+
553+
python -m profiling.sampling run --mode=wall script.py # do_sleep ~98%, do_compute ~1%
554+
python -m profiling.sampling run --mode=cpu script.py # do_sleep absent, do_compute dominates
555+
531556

532557
GIL mode
533558
--------
@@ -552,6 +577,90 @@ GIL?" and "why are my other threads starving?" It can also be useful in
552577
single-threaded programs to distinguish Python execution time from time spent
553578
in C extensions or I/O.
554579

580+
.. code-block:: python
581+
582+
import hashlib
583+
584+
def hash_work():
585+
# C extension - releases GIL during computation
586+
for _ in range(200):
587+
hashlib.sha256(b"data" * 250000).hexdigest()
588+
589+
def python_work():
590+
# Pure Python - holds GIL during computation
591+
for _ in range(3):
592+
sum(i**2 for i in range(1000000))
593+
594+
if __name__ == "__main__":
595+
hash_work()
596+
python_work()
597+
598+
::
599+
600+
python -m profiling.sampling run --mode=cpu script.py # hash_work ~42%, python_work ~38%
601+
python -m profiling.sampling run --mode=gil script.py # hash_work ~5%, python_work ~60%
602+
603+
604+
Exception mode
605+
--------------
606+
607+
Exception mode (``--mode=exception``) records samples only when a thread has
608+
an active exception::
609+
610+
python -m profiling.sampling run --mode=exception script.py
611+
612+
Samples are recorded in two situations: when an exception is being propagated
613+
up the call stack (after ``raise`` but before being caught), or when code is
614+
executing inside an ``except`` block where exception information is still
615+
present in the thread state.
616+
617+
The following example illustrates which code regions are captured:
618+
619+
.. code-block:: python
620+
621+
def example():
622+
try:
623+
raise ValueError("error") # Captured: exception being raised
624+
except ValueError:
625+
process_error() # Captured: inside except block
626+
finally:
627+
cleanup() # NOT captured: exception already handled
628+
629+
def example_propagating():
630+
try:
631+
try:
632+
raise ValueError("error")
633+
finally:
634+
cleanup() # Captured: exception propagating through
635+
except ValueError:
636+
pass
637+
638+
def example_no_exception():
639+
try:
640+
do_work()
641+
finally:
642+
cleanup() # NOT captured: no exception involved
643+
644+
Note that ``finally`` blocks are only captured when an exception is actively
645+
propagating through them. Once an ``except`` block finishes executing, Python
646+
clears the exception information before running any subsequent ``finally``
647+
block. Similarly, ``finally`` blocks that run during normal execution (when no
648+
exception was raised) are not captured because no exception state is present.
649+
650+
This mode is useful for understanding where your program spends time handling
651+
errors. Exception handling can be a significant source of overhead in code
652+
that uses exceptions for flow control (such as ``StopIteration`` in iterators)
653+
or in applications that process many error conditions (such as network servers
654+
handling connection failures).
655+
656+
Exception mode helps answer questions like "how much time is spent handling
657+
exceptions?" and "which exception handlers are the most expensive?" It can
658+
reveal hidden performance costs in code that catches and processes many
659+
exceptions, even when those exceptions are handled gracefully. For example,
660+
if a parsing library uses exceptions internally to signal format errors, this
661+
mode will capture time spent in those handlers even if the calling code never
662+
sees the exceptions.
663+
555664

556665
Output formats
557666
==============
@@ -890,6 +999,25 @@ stack often shows event loop internals rather than the logical flow of your
890999
coroutines. Async-aware mode addresses this by tracking which task is running
8911000
and presenting stacks that reflect the ``await`` chain.
8921001

1002+
.. code-block:: python
1003+
1004+
import asyncio
1005+
1006+
async def fetch(url):
1007+
await asyncio.sleep(0.1)
1008+
return url
1009+
1010+
async def main():
1011+
for _ in range(50):
1012+
await asyncio.gather(fetch("a"), fetch("b"), fetch("c"))
1013+
1014+
if __name__ == "__main__":
1015+
asyncio.run(main())
1016+
1017+
::
1018+
1019+
python -m profiling.sampling run --async-aware --flamegraph -o out.html script.py
1020+
8931021
.. note::
8941022

8951023
Async-aware profiling requires the target process to have the :mod:`asyncio`
@@ -1006,8 +1134,9 @@ Mode options
10061134

10071135
.. option:: --mode <mode>
10081136

1009-
Sampling mode: ``wall`` (default), ``cpu``, or ``gil``.
1010-
The ``cpu`` and ``gil`` modes are incompatible with ``--async-aware``.
1137+
Sampling mode: ``wall`` (default), ``cpu``, ``gil``, or ``exception``.
1138+
The ``cpu``, ``gil``, and ``exception`` modes are incompatible with
1139+
``--async-aware``.
10111140

10121141
.. option:: --async-mode <mode>
10131142

0 commit comments

Comments
 (0)