mirror of
https://github.com/python/cpython.git
synced 2026-05-04 09:31:02 +00:00
Merge branch 'main' into 3.15-calendar-colour
This commit is contained in:
commit
f25c42ce1c
491 changed files with 25812 additions and 6332 deletions
3
.gitattributes
vendored
3
.gitattributes
vendored
|
|
@ -34,6 +34,9 @@ Lib/test/xmltestdata/* noeol
|
|||
Lib/venv/scripts/common/activate text eol=lf
|
||||
Lib/venv/scripts/posix/* text eol=lf
|
||||
|
||||
# Prevent GitHub's web conflict editor from converting LF to CRLF
|
||||
*.rst text eol=lf
|
||||
|
||||
# CRLF files
|
||||
[attr]dos text eol=crlf
|
||||
|
||||
|
|
|
|||
3
.github/workflows/add-issue-header.yml
vendored
3
.github/workflows/add-issue-header.yml
vendored
|
|
@ -12,7 +12,8 @@ on:
|
|||
# Only ever run once
|
||||
- opened
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
add-header:
|
||||
|
|
|
|||
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
|
|
@ -11,7 +11,8 @@ on:
|
|||
- 'main'
|
||||
- '3.*'
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#concurrency
|
||||
|
|
@ -353,7 +354,7 @@ jobs:
|
|||
with:
|
||||
persist-credentials: false
|
||||
- name: Build and test
|
||||
run: ./Android/android.py ci --fast-ci ${{ matrix.arch }}-linux-android
|
||||
run: python3 Platforms/Android ci --fast-ci ${{ matrix.arch }}-linux-android
|
||||
|
||||
build-ios:
|
||||
name: iOS
|
||||
|
|
@ -612,6 +613,7 @@ jobs:
|
|||
needs.build-context.outputs.run-ci-fuzz == 'true'
|
||||
|| needs.build-context.outputs.run-ci-fuzz-stdlib == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
|
|||
3
.github/workflows/jit.yml
vendored
3
.github/workflows/jit.yml
vendored
|
|
@ -15,7 +15,8 @@ on:
|
|||
paths: *paths
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
|
|
|
|||
3
.github/workflows/lint.yml
vendored
3
.github/workflows/lint.yml
vendored
|
|
@ -2,7 +2,8 @@ name: Lint
|
|||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
4
.github/workflows/mypy.yml
vendored
4
.github/workflows/mypy.yml
vendored
|
|
@ -19,6 +19,7 @@ on:
|
|||
- "Tools/build/consts_getter.py"
|
||||
- "Tools/build/deepfreeze.py"
|
||||
- "Tools/build/generate-build-details.py"
|
||||
- "Tools/build/generate_levenshtein_examples.py"
|
||||
- "Tools/build/generate_sbom.py"
|
||||
- "Tools/build/generate_stdlib_module_names.py"
|
||||
- "Tools/build/mypy.ini"
|
||||
|
|
@ -33,7 +34,8 @@ on:
|
|||
- "Tools/requirements-dev.txt"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: 1
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ on:
|
|||
types:
|
||||
- opened
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
notify-new-bugs-announce:
|
||||
|
|
|
|||
3
.github/workflows/require-pr-label.yml
vendored
3
.github/workflows/require-pr-label.yml
vendored
|
|
@ -4,7 +4,8 @@ on:
|
|||
pull_request:
|
||||
types: [opened, reopened, labeled, unlabeled, synchronize]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
label-dnm:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ name: Reusable C API Docs Check
|
|||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ name: Reusable check HTML IDs
|
|||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
3
.github/workflows/reusable-cifuzz.yml
vendored
3
.github/workflows/reusable-cifuzz.yml
vendored
|
|
@ -13,7 +13,8 @@ on:
|
|||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
cifuzz:
|
||||
|
|
|
|||
3
.github/workflows/reusable-context.yml
vendored
3
.github/workflows/reusable-context.yml
vendored
|
|
@ -54,7 +54,8 @@ on: # yamllint disable-line rule:truthy
|
|||
description: Whether to run the Windows tests
|
||||
value: ${{ jobs.compute-changes.outputs.run-windows-tests }} # bool
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
compute-changes:
|
||||
|
|
|
|||
3
.github/workflows/reusable-docs.yml
vendored
3
.github/workflows/reusable-docs.yml
vendored
|
|
@ -4,7 +4,8 @@ on:
|
|||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
|
|
|
|||
3
.github/workflows/reusable-emscripten.yml
vendored
3
.github/workflows/reusable-emscripten.yml
vendored
|
|
@ -3,7 +3,8 @@ name: Reusable Emscripten
|
|||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
3
.github/workflows/reusable-macos.yml
vendored
3
.github/workflows/reusable-macos.yml
vendored
|
|
@ -12,7 +12,8 @@ on:
|
|||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
15
.github/workflows/reusable-san.yml
vendored
15
.github/workflows/reusable-san.yml
vendored
|
|
@ -12,7 +12,8 @@ on:
|
|||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
@ -39,17 +40,15 @@ jobs:
|
|||
# Install clang
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 20
|
||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-20 100
|
||||
sudo update-alternatives --set clang /usr/bin/clang-20
|
||||
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-20 100
|
||||
sudo update-alternatives --set clang++ /usr/bin/clang++-20
|
||||
|
||||
if [ "${SANITIZER}" = "TSan" ]; then
|
||||
sudo ./llvm.sh 17 # gh-121946: llvm-18 package is temporarily broken
|
||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 100
|
||||
sudo update-alternatives --set clang /usr/bin/clang-17
|
||||
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-17 100
|
||||
sudo update-alternatives --set clang++ /usr/bin/clang++-17
|
||||
# Reduce ASLR to avoid TSan crashing
|
||||
sudo sysctl -w vm.mmap_rnd_bits=28
|
||||
else
|
||||
sudo ./llvm.sh 20
|
||||
fi
|
||||
|
||||
- name: Sanitizer option setup
|
||||
|
|
|
|||
3
.github/workflows/reusable-ubuntu.yml
vendored
3
.github/workflows/reusable-ubuntu.yml
vendored
|
|
@ -23,7 +23,8 @@ on:
|
|||
type: string
|
||||
default: ''
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
3
.github/workflows/reusable-wasi.yml
vendored
3
.github/workflows/reusable-wasi.yml
vendored
|
|
@ -3,7 +3,8 @@ name: Reusable WASI
|
|||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
3
.github/workflows/reusable-windows-msi.yml
vendored
3
.github/workflows/reusable-windows-msi.yml
vendored
|
|
@ -8,7 +8,8 @@ on:
|
|||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
3
.github/workflows/reusable-windows.yml
vendored
3
.github/workflows/reusable-windows.yml
vendored
|
|
@ -17,7 +17,8 @@ on:
|
|||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
|
|
|||
3
.github/workflows/stale.yml
vendored
3
.github/workflows/stale.yml
vendored
|
|
@ -4,7 +4,8 @@ on:
|
|||
schedule:
|
||||
- cron: "0 */6 * * *"
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
|
|
|||
3
.github/workflows/tail-call.yml
vendored
3
.github/workflows/tail-call.yml
vendored
|
|
@ -11,7 +11,8 @@ on:
|
|||
paths: *paths
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ on:
|
|||
- '.github/workflows/verify-ensurepip-wheels.yml'
|
||||
- 'Tools/build/verify_ensurepip_wheels.py'
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
|
|
|
|||
3
.github/workflows/verify-expat.yml
vendored
3
.github/workflows/verify-expat.yml
vendored
|
|
@ -11,7 +11,8 @@ on:
|
|||
- 'Modules/expat/**'
|
||||
- '.github/workflows/verify-expat.yml'
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -5,6 +5,7 @@
|
|||
*.cover
|
||||
*.iml
|
||||
*.o
|
||||
*.o.tmp
|
||||
*.lto
|
||||
*.a
|
||||
*.so
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
.. _allocating-objects:
|
||||
|
||||
Allocating Objects on the Heap
|
||||
Allocating objects on the heap
|
||||
==============================
|
||||
|
||||
|
||||
|
|
@ -153,10 +153,12 @@ Allocating Objects on the Heap
|
|||
To allocate and create extension modules.
|
||||
|
||||
|
||||
Deprecated aliases
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Soft-deprecated aliases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These are :term:`soft deprecated` aliases to existing functions and macros.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
These are aliases to existing functions and macros.
|
||||
They exist solely for backwards compatibility.
|
||||
|
||||
|
||||
|
|
@ -164,7 +166,7 @@ They exist solely for backwards compatibility.
|
|||
:widths: auto
|
||||
:header-rows: 1
|
||||
|
||||
* * Deprecated alias
|
||||
* * Soft-deprecated alias
|
||||
* Function
|
||||
* * .. c:macro:: PyObject_NEW(type, typeobj)
|
||||
* :c:macro:`PyObject_New`
|
||||
|
|
|
|||
|
|
@ -258,7 +258,9 @@ readonly, format
|
|||
|
||||
.. c:macro:: PyBUF_WRITEABLE
|
||||
|
||||
This is a :term:`soft deprecated` alias to :c:macro:`PyBUF_WRITABLE`.
|
||||
This is an alias to :c:macro:`PyBUF_WRITABLE`.
|
||||
|
||||
.. soft-deprecated:: 3.13
|
||||
|
||||
.. c:macro:: PyBUF_FORMAT
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ called with a non-bytes parameter.
|
|||
*len* on success, and ``NULL`` on failure. If *v* is ``NULL``, the contents of
|
||||
the bytes object are uninitialized.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
``PyBytes_FromStringAndSize(NULL, len)`` is :term:`soft deprecated`,
|
||||
use the :c:type:`PyBytesWriter` API instead.
|
||||
.. soft-deprecated:: 3.15
|
||||
Use the :c:type:`PyBytesWriter` API instead of
|
||||
``PyBytes_FromStringAndSize(NULL, len)``.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyBytes_FromFormat(const char *format, ...)
|
||||
|
|
@ -238,9 +238,8 @@ called with a non-bytes parameter.
|
|||
*\*bytes* is set to ``NULL``, :exc:`MemoryError` is set, and ``-1`` is
|
||||
returned.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The function is :term:`soft deprecated`,
|
||||
use the :c:type:`PyBytesWriter` API instead.
|
||||
.. soft-deprecated:: 3.15
|
||||
Use the :c:type:`PyBytesWriter` API instead.
|
||||
|
||||
|
||||
.. c:function:: PyObject *PyBytes_Repr(PyObject *bytes, int smartquotes)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ bound into a function.
|
|||
|
||||
.. c:function:: PyObject *PyCode_Optimize(PyObject *code, PyObject *consts, PyObject *names, PyObject *lnotab_obj)
|
||||
|
||||
This is a :term:`soft deprecated` function that does nothing.
|
||||
This is a function that does nothing.
|
||||
|
||||
Prior to Python 3.10, this function would perform basic optimizations to a
|
||||
code object.
|
||||
|
|
@ -220,6 +220,8 @@ bound into a function.
|
|||
.. versionchanged:: 3.10
|
||||
This function now does nothing.
|
||||
|
||||
.. soft-deprecated:: 3.13
|
||||
|
||||
|
||||
.. _c_codeobject_flags:
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ found in the dictionary of type objects.
|
|||
|
||||
.. c:macro:: PyDescr_COMMON
|
||||
|
||||
This is a :term:`soft deprecated` macro including the common fields for a
|
||||
This is a macro including the common fields for a
|
||||
descriptor object.
|
||||
|
||||
This was included in Python's C API by mistake; do not use it in extensions.
|
||||
|
|
@ -148,6 +148,8 @@ found in the dictionary of type objects.
|
|||
descriptor protocol (:c:member:`~PyTypeObject.tp_descr_get` and
|
||||
:c:member:`~PyTypeObject.tp_descr_set`).
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
|
||||
Built-in descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -76,6 +76,11 @@ Dictionary objects
|
|||
|
||||
The first argument can be a :class:`dict` or a :class:`frozendict`.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Also accept :class:`frozendict`.
|
||||
|
||||
|
|
@ -105,6 +110,11 @@ Dictionary objects
|
|||
``0`` on success or ``-1`` on failure. This function *does not* steal a
|
||||
reference to *val*.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
|
||||
.. c:function:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val)
|
||||
|
||||
|
|
@ -120,6 +130,11 @@ Dictionary objects
|
|||
If *key* is not in the dictionary, :exc:`KeyError` is raised.
|
||||
Return ``0`` on success or ``-1`` on failure.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
|
||||
.. c:function:: int PyDict_DelItemString(PyObject *p, const char *key)
|
||||
|
||||
|
|
@ -140,6 +155,11 @@ Dictionary objects
|
|||
|
||||
The first argument can be a :class:`dict` or a :class:`frozendict`.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
|
|
@ -162,6 +182,13 @@ Dictionary objects
|
|||
:meth:`~object.__eq__` methods are silently ignored.
|
||||
Prefer the :c:func:`PyDict_GetItemWithError` function instead.
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded build`, the returned
|
||||
:term:`borrowed reference` may become invalid if another thread modifies
|
||||
the dictionary concurrently. Prefer :c:func:`PyDict_GetItemRef`, which
|
||||
returns a :term:`strong reference`.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
Calling this API without an :term:`attached thread state` had been allowed for historical
|
||||
reason. It is no longer allowed.
|
||||
|
|
@ -177,6 +204,13 @@ Dictionary objects
|
|||
occurred. Return ``NULL`` **without** an exception set if the key
|
||||
wasn't present.
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded build`, the returned
|
||||
:term:`borrowed reference` may become invalid if another thread modifies
|
||||
the dictionary concurrently. Prefer :c:func:`PyDict_GetItemRef`, which
|
||||
returns a :term:`strong reference`.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Also accept :class:`frozendict`.
|
||||
|
||||
|
|
@ -195,6 +229,13 @@ Dictionary objects
|
|||
Prefer using the :c:func:`PyDict_GetItemWithError` function with your own
|
||||
:c:func:`PyUnicode_FromString` *key* instead.
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded build`, the returned
|
||||
:term:`borrowed reference` may become invalid if another thread modifies
|
||||
the dictionary concurrently. Prefer :c:func:`PyDict_GetItemStringRef`,
|
||||
which returns a :term:`strong reference`.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Also accept :class:`frozendict`.
|
||||
|
||||
|
|
@ -221,6 +262,14 @@ Dictionary objects
|
|||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded build`, the returned
|
||||
:term:`borrowed reference` may become invalid if another thread modifies
|
||||
the dictionary concurrently. Prefer :c:func:`PyDict_SetDefaultRef`,
|
||||
which returns a :term:`strong reference`.
|
||||
|
||||
|
||||
|
||||
.. c:function:: int PyDict_SetDefaultRef(PyObject *p, PyObject *key, PyObject *default_value, PyObject **result)
|
||||
|
||||
|
|
@ -240,6 +289,11 @@ Dictionary objects
|
|||
These may refer to the same object: in that case you hold two separate
|
||||
references to it.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
|
||||
|
|
@ -257,6 +311,11 @@ Dictionary objects
|
|||
Similar to :meth:`dict.pop`, but without the default value and
|
||||
not raising :exc:`KeyError` if the key is missing.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
|
||||
|
|
@ -403,6 +462,13 @@ Dictionary objects
|
|||
only be added if there is not a matching key in *a*. Return ``0`` on
|
||||
success or ``-1`` if an exception was raised.
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded build`, when *b* is a
|
||||
:class:`dict` (with the standard iterator), both *a* and *b* are locked
|
||||
for the duration of the operation. When *b* is a non-dict mapping, only
|
||||
*a* is locked; *b* may be concurrently modified by another thread.
|
||||
|
||||
|
||||
.. c:function:: int PyDict_Update(PyObject *a, PyObject *b)
|
||||
|
||||
|
|
@ -412,6 +478,13 @@ Dictionary objects
|
|||
argument has no "keys" attribute. Return ``0`` on success or ``-1`` if an
|
||||
exception was raised.
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded build`, when *b* is a
|
||||
:class:`dict` (with the standard iterator), both *a* and *b* are locked
|
||||
for the duration of the operation. When *b* is a non-dict mapping, only
|
||||
*a* is locked; *b* may be concurrently modified by another thread.
|
||||
|
||||
|
||||
.. c:function:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override)
|
||||
|
||||
|
|
@ -427,6 +500,13 @@ Dictionary objects
|
|||
if override or key not in a:
|
||||
a[key] = value
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded <free threading>` build, only *a* is locked.
|
||||
The iteration over *seq2* is not synchronized; *seq2* may be concurrently
|
||||
modified by another thread.
|
||||
|
||||
|
||||
.. c:function:: int PyDict_AddWatcher(PyDict_WatchCallback callback)
|
||||
|
||||
Register *callback* as a dictionary watcher. Return a non-negative integer
|
||||
|
|
@ -434,6 +514,13 @@ Dictionary objects
|
|||
of error (e.g. no more watcher IDs available), return ``-1`` and set an
|
||||
exception.
|
||||
|
||||
.. note::
|
||||
|
||||
This function is not internally synchronized. In the
|
||||
:term:`free-threaded <free threading>` build, callers should ensure no
|
||||
concurrent calls to :c:func:`PyDict_AddWatcher` or
|
||||
:c:func:`PyDict_ClearWatcher` are in progress.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:function:: int PyDict_ClearWatcher(int watcher_id)
|
||||
|
|
@ -442,6 +529,13 @@ Dictionary objects
|
|||
:c:func:`PyDict_AddWatcher`. Return ``0`` on success, ``-1`` on error (e.g.
|
||||
if the given *watcher_id* was never registered.)
|
||||
|
||||
.. note::
|
||||
|
||||
This function is not internally synchronized. In the
|
||||
:term:`free-threaded <free threading>` build, callers should ensure no
|
||||
concurrent calls to :c:func:`PyDict_AddWatcher` or
|
||||
:c:func:`PyDict_ClearWatcher` are in progress.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:function:: int PyDict_Watch(int watcher_id, PyObject *dict)
|
||||
|
|
|
|||
|
|
@ -818,7 +818,7 @@ Exception Classes
|
|||
|
||||
.. c:macro:: PyException_HEAD
|
||||
|
||||
This is a :term:`soft deprecated` macro including the base fields for an
|
||||
This is a macro including the base fields for an
|
||||
exception object.
|
||||
|
||||
This was included in Python's C API by mistake and is not designed for use
|
||||
|
|
@ -826,6 +826,8 @@ Exception Classes
|
|||
:c:func:`PyErr_NewException` or otherwise create a class inheriting from
|
||||
:c:data:`PyExc_BaseException`.
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
|
||||
Exception Objects
|
||||
=================
|
||||
|
|
|
|||
|
|
@ -191,10 +191,10 @@ the :c:data:`Py_mod_multiple_interpreters` slot.
|
|||
``PyInit`` function
|
||||
...................
|
||||
|
||||
.. deprecated:: 3.15
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
This functionality is :term:`soft deprecated`.
|
||||
It will not get new features, but there are no plans to remove it.
|
||||
This functionality will not get new features,
|
||||
but there are no plans to remove it.
|
||||
|
||||
Instead of :c:func:`PyModExport_modulename`, an extension module can define
|
||||
an older-style :dfn:`initialization function` with the signature:
|
||||
|
|
@ -272,10 +272,9 @@ For example, a module called ``spam`` would be defined like this::
|
|||
Legacy single-phase initialization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. deprecated:: 3.15
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
Single-phase initialization is :term:`soft deprecated`.
|
||||
It is a legacy mechanism to initialize extension
|
||||
Single-phase initialization is a legacy mechanism to initialize extension
|
||||
modules, with known drawbacks and design flaws. Extension module authors
|
||||
are encouraged to use multi-phase initialization instead.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
.. _fileobjects:
|
||||
|
||||
File Objects
|
||||
File objects
|
||||
------------
|
||||
|
||||
.. index:: pair: object; file
|
||||
|
|
@ -136,11 +136,12 @@ the :mod:`io` APIs instead.
|
|||
failure; the appropriate exception will be set.
|
||||
|
||||
|
||||
Deprecated API
|
||||
^^^^^^^^^^^^^^
|
||||
Soft-deprecated API
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
These are :term:`soft deprecated` APIs that were included in Python's C API
|
||||
These are APIs that were included in Python's C API
|
||||
by mistake. They are documented solely for completeness; use other
|
||||
``PyFile*`` APIs instead.
|
||||
|
||||
|
|
|
|||
|
|
@ -86,8 +86,7 @@ Floating-Point Objects
|
|||
It is equivalent to the :c:macro:`!INFINITY` macro from the C11 standard
|
||||
``<math.h>`` header.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
|
||||
.. c:macro:: Py_NAN
|
||||
|
|
@ -103,8 +102,7 @@ Floating-Point Objects
|
|||
|
||||
Equivalent to :c:macro:`!INFINITY`.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.14
|
||||
|
||||
|
||||
.. c:macro:: Py_MATH_E
|
||||
|
|
@ -161,8 +159,8 @@ Floating-Point Objects
|
|||
that is, it is normal, subnormal or zero, but not infinite or NaN.
|
||||
Return ``0`` otherwise.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The macro is :term:`soft deprecated`. Use :c:macro:`!isfinite` instead.
|
||||
.. soft-deprecated:: 3.14
|
||||
Use :c:macro:`!isfinite` instead.
|
||||
|
||||
|
||||
.. c:macro:: Py_IS_INFINITY(X)
|
||||
|
|
@ -170,8 +168,8 @@ Floating-Point Objects
|
|||
Return ``1`` if the given floating-point number *X* is positive or negative
|
||||
infinity. Return ``0`` otherwise.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The macro is :term:`soft deprecated`. Use :c:macro:`!isinf` instead.
|
||||
.. soft-deprecated:: 3.14
|
||||
Use :c:macro:`!isinf` instead.
|
||||
|
||||
|
||||
.. c:macro:: Py_IS_NAN(X)
|
||||
|
|
@ -179,8 +177,8 @@ Floating-Point Objects
|
|||
Return ``1`` if the given floating-point number *X* is a not-a-number (NaN)
|
||||
value. Return ``0`` otherwise.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The macro is :term:`soft deprecated`. Use :c:macro:`!isnan` instead.
|
||||
.. soft-deprecated:: 3.14
|
||||
Use :c:macro:`!isnan` instead.
|
||||
|
||||
|
||||
Pack and Unpack functions
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.. highlight:: c
|
||||
|
||||
Frame Objects
|
||||
Frame objects
|
||||
-------------
|
||||
|
||||
.. c:type:: PyFrameObject
|
||||
|
|
@ -147,7 +147,7 @@ See also :ref:`Reflection <reflection>`.
|
|||
Return the line number that *frame* is currently executing.
|
||||
|
||||
|
||||
Frame Locals Proxies
|
||||
Frame locals proxies
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 3.13
|
||||
|
|
@ -169,7 +169,7 @@ See :pep:`667` for more information.
|
|||
Return non-zero if *obj* is a frame :func:`locals` proxy.
|
||||
|
||||
|
||||
Legacy Local Variable APIs
|
||||
Legacy local variable APIs
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These APIs are :term:`soft deprecated`. As of Python 3.13, they do nothing.
|
||||
|
|
@ -178,40 +178,34 @@ They exist solely for backwards compatibility.
|
|||
|
||||
.. c:function:: void PyFrame_LocalsToFast(PyFrameObject *f, int clear)
|
||||
|
||||
This function is :term:`soft deprecated` and does nothing.
|
||||
|
||||
Prior to Python 3.13, this function would copy the :attr:`~frame.f_locals`
|
||||
attribute of *f* to the internal "fast" array of local variables, allowing
|
||||
changes in frame objects to be visible to the interpreter. If *clear* was
|
||||
true, this function would process variables that were unset in the locals
|
||||
dictionary.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
.. soft-deprecated:: 3.13
|
||||
This function now does nothing.
|
||||
|
||||
|
||||
.. c:function:: void PyFrame_FastToLocals(PyFrameObject *f)
|
||||
|
||||
This function is :term:`soft deprecated` and does nothing.
|
||||
|
||||
Prior to Python 3.13, this function would copy the internal "fast" array
|
||||
of local variables (which is used by the interpreter) to the
|
||||
:attr:`~frame.f_locals` attribute of *f*, allowing changes in local
|
||||
variables to be visible to frame objects.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
.. soft-deprecated:: 3.13
|
||||
This function now does nothing.
|
||||
|
||||
|
||||
.. c:function:: int PyFrame_FastToLocalsWithError(PyFrameObject *f)
|
||||
|
||||
This function is :term:`soft deprecated` and does nothing.
|
||||
|
||||
Prior to Python 3.13, this function was similar to
|
||||
:c:func:`PyFrame_FastToLocals`, but would return ``0`` on success, and
|
||||
``-1`` with an exception set on failure.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
.. soft-deprecated:: 3.13
|
||||
This function now does nothing.
|
||||
|
||||
|
||||
|
|
@ -219,7 +213,7 @@ They exist solely for backwards compatibility.
|
|||
:pep:`667`
|
||||
|
||||
|
||||
Internal Frames
|
||||
Internal frames
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Unless using :pep:`523`, you will not need this.
|
||||
|
|
@ -249,5 +243,3 @@ Unless using :pep:`523`, you will not need this.
|
|||
Return the currently executing line number, or -1 if there is no line number.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@ Deprecated API
|
|||
|
||||
.. c:macro:: PyAsyncGenASend_CheckExact(op)
|
||||
|
||||
This is a :term:`soft deprecated` API that was included in Python's C API
|
||||
This is an API that was included in Python's C API
|
||||
by mistake.
|
||||
|
||||
It is solely here for completeness; do not use this API.
|
||||
|
||||
.. soft-deprecated:: 3.14
|
||||
|
|
|
|||
|
|
@ -410,6 +410,11 @@ Initializing and finalizing the interpreter
|
|||
(zero) if not. After :c:func:`Py_FinalizeEx` is called, this returns false until
|
||||
:c:func:`Py_Initialize` is called again.
|
||||
|
||||
.. versionchanged:: next
|
||||
This function no longer returns true until initialization has fully
|
||||
completed, including import of the :mod:`site` module. Previously it
|
||||
could return true while :c:func:`Py_Initialize` was still running.
|
||||
|
||||
|
||||
.. c:function:: int Py_IsFinalizing()
|
||||
|
||||
|
|
|
|||
|
|
@ -536,16 +536,14 @@ have been standardized in C11 (or previous standards).
|
|||
|
||||
Use the standard ``alignas`` specifier rather than this macro.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
.. c:macro:: PY_FORMAT_SIZE_T
|
||||
|
||||
The :c:func:`printf` formatting modifier for :c:type:`size_t`.
|
||||
Use ``"z"`` directly instead.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
.. c:macro:: Py_LL(number)
|
||||
Py_ULL(number)
|
||||
|
|
@ -558,8 +556,7 @@ have been standardized in C11 (or previous standards).
|
|||
|
||||
Consider using the C99 standard suffixes ``LL`` and ``LLU`` directly.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
.. c:macro:: PY_LONG_LONG
|
||||
PY_INT32_T
|
||||
|
|
@ -572,8 +569,7 @@ have been standardized in C11 (or previous standards).
|
|||
respectively.
|
||||
Historically, these types needed compiler-specific extensions.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
These macros are :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
.. c:macro:: PY_LLONG_MIN
|
||||
PY_LLONG_MAX
|
||||
|
|
@ -587,16 +583,14 @@ have been standardized in C11 (or previous standards).
|
|||
The required header, ``<limits.h>``,
|
||||
:ref:`is included <capi-system-includes>` in ``Python.h``.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
These macros are :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
.. c:macro:: Py_MEMCPY(dest, src, n)
|
||||
|
||||
This is a :term:`soft deprecated` alias to :c:func:`!memcpy`.
|
||||
Use :c:func:`!memcpy` directly instead.
|
||||
This is an alias to :c:func:`!memcpy`.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.14
|
||||
Use :c:func:`!memcpy` directly instead.
|
||||
|
||||
.. c:macro:: Py_UNICODE_SIZE
|
||||
|
||||
|
|
@ -606,29 +600,25 @@ have been standardized in C11 (or previous standards).
|
|||
The required header for the latter, ``<limits.h>``,
|
||||
:ref:`is included <capi-system-includes>` in ``Python.h``.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
.. c:macro:: Py_UNICODE_WIDE
|
||||
|
||||
Defined if ``wchar_t`` can hold a Unicode character (UCS-4).
|
||||
Use ``sizeof(wchar_t) >= 4`` instead
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
.. c:macro:: Py_VA_COPY
|
||||
|
||||
This is a :term:`soft deprecated` alias to the C99-standard ``va_copy``
|
||||
function.
|
||||
This is an alias to the C99-standard ``va_copy`` function.
|
||||
|
||||
Historically, this would use a compiler-specific method to copy a ``va_list``.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
This is now an alias to ``va_copy``.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
The macro is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
|
||||
.. _api-objects:
|
||||
|
|
|
|||
|
|
@ -197,12 +197,10 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
|
||||
.. c:function:: long PyLong_AS_LONG(PyObject *obj)
|
||||
|
||||
A :term:`soft deprecated` alias.
|
||||
Exactly equivalent to the preferred ``PyLong_AsLong``. In particular,
|
||||
it can fail with :exc:`OverflowError` or another exception.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The function is soft deprecated.
|
||||
.. soft-deprecated:: 3.14
|
||||
|
||||
.. c:function:: int PyLong_AsInt(PyObject *obj)
|
||||
|
||||
|
|
|
|||
|
|
@ -685,6 +685,12 @@ remove it.
|
|||
Usually, there is only one variable of this type for each extension module
|
||||
defined this way.
|
||||
|
||||
The struct, including all members, is part of the
|
||||
:ref:`Stable ABI <stable-abi>` for non-free-threaded builds (``abi3``).
|
||||
In the Stable ABI for free-threaded builds (``abi3t``),
|
||||
this struct is opaque, and unusable in practice; see :ref:`pymoduledef_slot`
|
||||
for a replacement.
|
||||
|
||||
.. c:member:: PyModuleDef_Base m_base
|
||||
|
||||
Always initialize this member to :c:macro:`PyModuleDef_HEAD_INIT`:
|
||||
|
|
@ -695,6 +701,11 @@ remove it.
|
|||
|
||||
The type of :c:member:`!PyModuleDef.m_base`.
|
||||
|
||||
The struct is part of the :ref:`Stable ABI <stable-abi>` for
|
||||
non-free-threaded builds (``abi3``).
|
||||
In the Stable ABI for Free-Threaded Builds
|
||||
(``abi3t``), this struct is opaque, and unusable in practice.
|
||||
|
||||
.. c:macro:: PyModuleDef_HEAD_INIT
|
||||
|
||||
The required initial value for :c:member:`!PyModuleDef.m_base`.
|
||||
|
|
@ -954,9 +965,7 @@ or code that creates modules dynamically.
|
|||
// PyModule_AddObject() stole a reference to obj:
|
||||
// Py_XDECREF(obj) is not needed here.
|
||||
|
||||
.. deprecated:: 3.13
|
||||
|
||||
:c:func:`PyModule_AddObject` is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.13
|
||||
|
||||
|
||||
.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
|
||||
|
|
|
|||
|
|
@ -205,6 +205,4 @@ would typically correspond to a Python function.
|
|||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
.. deprecated:: 3.14
|
||||
|
||||
This function is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.14
|
||||
|
|
|
|||
|
|
@ -109,9 +109,8 @@ Sequence Protocol
|
|||
|
||||
Alias for :c:func:`PySequence_Contains`.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The function is :term:`soft deprecated` and should no longer be used to
|
||||
write new code.
|
||||
.. soft-deprecated:: 3.14
|
||||
The function should no longer be used to write new code.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t PySequence_Index(PyObject *o, PyObject *value)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,11 @@ the constructor functions work with any iterable Python object.
|
|||
actually iterable. The constructor is also useful for copying a set
|
||||
(``c=set(s)``).
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *iterable* is a :class:`set`, :class:`frozenset`, :class:`dict` or :class:`frozendict`.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyFrozenSet_New(PyObject *iterable)
|
||||
|
||||
|
|
@ -97,6 +102,11 @@ the constructor functions work with any iterable Python object.
|
|||
set on success or ``NULL`` on failure. Raise :exc:`TypeError` if *iterable* is
|
||||
not actually iterable.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *iterable* is a :class:`set`, :class:`frozenset`, :class:`dict` or :class:`frozendict`.
|
||||
|
||||
|
||||
The following functions and macros are available for instances of :class:`set`
|
||||
or :class:`frozenset` or instances of their subtypes.
|
||||
|
|
@ -124,6 +134,10 @@ or :class:`frozenset` or instances of their subtypes.
|
|||
the *key* is unhashable. Raise :exc:`SystemError` if *anyset* is not a
|
||||
:class:`set`, :class:`frozenset`, or an instance of a subtype.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
|
||||
|
||||
|
|
@ -135,6 +149,12 @@ or :class:`frozenset` or instances of their subtypes.
|
|||
:exc:`SystemError` if *set* is not an instance of :class:`set` or its
|
||||
subtype.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
|
||||
|
||||
The following functions are available for instances of :class:`set` or its
|
||||
subtypes but not for instances of :class:`frozenset` or its subtypes.
|
||||
|
|
@ -149,6 +169,11 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
|
|||
temporary frozensets. Raise :exc:`SystemError` if *set* is not an
|
||||
instance of :class:`set` or its subtype.
|
||||
|
||||
.. note::
|
||||
|
||||
The operation is atomic on :term:`free threading <free-threaded build>`
|
||||
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PySet_Pop(PyObject *set)
|
||||
|
||||
|
|
@ -164,13 +189,19 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
|
|||
success. Return ``-1`` and raise :exc:`SystemError` if *set* is not an instance of
|
||||
:class:`set` or its subtype.
|
||||
|
||||
.. note::
|
||||
|
||||
In the :term:`free-threaded build`, the set is emptied before its entries
|
||||
are cleared, so other threads will observe an empty set rather than
|
||||
intermediate states.
|
||||
|
||||
|
||||
Deprecated API
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:macro:: PySet_MINSIZE
|
||||
|
||||
A :term:`soft deprecated` constant representing the size of an internal
|
||||
A constant representing the size of an internal
|
||||
preallocated table inside :c:type:`PySetObject` instances.
|
||||
|
||||
This is documented solely for completeness, as there are no guarantees
|
||||
|
|
@ -180,3 +211,5 @@ Deprecated API
|
|||
:c:macro:`!PySet_MINSIZE` can be replaced with a small constant like ``8``.
|
||||
|
||||
If looking for the size of a set, use :c:func:`PySet_Size` instead.
|
||||
|
||||
.. soft-deprecated:: 3.14
|
||||
|
|
|
|||
|
|
@ -51,145 +51,212 @@ It is generally intended for specialized, low-level tools like debuggers.
|
|||
Projects that use this API are expected to follow
|
||||
CPython development and spend extra effort adjusting to changes.
|
||||
|
||||
.. _stable-abi:
|
||||
.. _stable-application-binary-interface:
|
||||
|
||||
Stable Application Binary Interface
|
||||
===================================
|
||||
Stable Application Binary Interfaces
|
||||
====================================
|
||||
|
||||
For simplicity, this document talks about *extensions*, but the Limited API
|
||||
and Stable ABI work the same way for all uses of the API – for example,
|
||||
embedding Python.
|
||||
|
||||
.. _limited-c-api:
|
||||
|
||||
Limited C API
|
||||
-------------
|
||||
|
||||
Python 3.2 introduced the *Limited API*, a subset of Python's C API.
|
||||
Extensions that only use the Limited API can be
|
||||
compiled once and be loaded on multiple versions of Python.
|
||||
Contents of the Limited API are :ref:`listed below <limited-api-list>`.
|
||||
|
||||
.. c:macro:: Py_LIMITED_API
|
||||
|
||||
Define this macro before including ``Python.h`` to opt in to only use
|
||||
the Limited API, and to select the Limited API version.
|
||||
|
||||
Define ``Py_LIMITED_API`` to the value of :c:macro:`PY_VERSION_HEX`
|
||||
corresponding to the lowest Python version your extension supports.
|
||||
The extension will be ABI-compatible with all Python 3 releases
|
||||
from the specified one onward, and can use Limited API introduced up to that
|
||||
version.
|
||||
|
||||
Rather than using the ``PY_VERSION_HEX`` macro directly, hardcode a minimum
|
||||
minor version (e.g. ``0x030A0000`` for Python 3.10) for stability when
|
||||
compiling with future Python versions.
|
||||
|
||||
You can also define ``Py_LIMITED_API`` to ``3``. This works the same as
|
||||
``0x03020000`` (Python 3.2, the version that introduced Limited API).
|
||||
|
||||
.. c:macro:: Py_TARGET_ABI3T
|
||||
|
||||
Define this macro before including ``Python.h`` to opt in to only use
|
||||
the Limited API for :term:`free-threaded builds <free-threaded build>`,
|
||||
and to select the Limited API version.
|
||||
|
||||
.. seealso:: :pep:`803`
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
|
||||
.. _stable-abi:
|
||||
|
||||
Stable ABI
|
||||
----------
|
||||
|
||||
To enable this, Python provides a *Stable ABI*: a set of symbols that will
|
||||
remain ABI-compatible across Python 3.x versions.
|
||||
Python's :dfn:`Stable ABI` allows extensions to be compatible with multiple
|
||||
versions of Python, without recompilation.
|
||||
|
||||
.. note::
|
||||
|
||||
The Stable ABI prevents ABI issues, like linker errors due to missing
|
||||
symbols or data corruption due to changes in structure layouts or function
|
||||
signatures.
|
||||
However, other changes in Python can change the *behavior* of extensions.
|
||||
See Python's Backwards Compatibility Policy (:pep:`387`) for details.
|
||||
For simplicity, this document talks about *extensions*, but Stable ABI
|
||||
works the same way for all uses of the API – for example, embedding Python.
|
||||
|
||||
The Stable ABI contains symbols exposed in the :ref:`Limited API
|
||||
<limited-c-api>`, but also other ones – for example, functions necessary to
|
||||
support older versions of the Limited API.
|
||||
There are two Stable ABIs:
|
||||
|
||||
On Windows, extensions that use the Stable ABI should be linked against
|
||||
- ``abi3``, introduced in Python 3.2, is compatible with
|
||||
**non**-:term:`free-threaded <free-threaded build>` builds of CPython.
|
||||
|
||||
- ``abi3t``, introduced in Python 3.15, is compatible with
|
||||
:term:`free-threaded <free-threaded build>` builds of CPython.
|
||||
It has stricter API limitations than ``abi3``.
|
||||
|
||||
.. versionadded:: next
|
||||
|
||||
``abi3t`` was added in :pep:`803`
|
||||
|
||||
It is possible for an extension to be compiled for *both* ``abi3`` and
|
||||
``abi3t`` at the same time; the result will be compatible with
|
||||
both free-threaded and non-free-threaded builds of Python.
|
||||
Currently, this has no downsides compared to compiling for ``abi3t`` only.
|
||||
|
||||
Each Stable ABI is versioned using the first two numbers of the Python version.
|
||||
For example, Stable ABI 3.14 corresponds to Python 3.14.
|
||||
An extension compiled for Stable ABI 3.x is ABI-compatible with Python 3.x
|
||||
and above.
|
||||
|
||||
Extensions that target a stable ABI must only use a limited subset of
|
||||
the C API. This subset is known as the :dfn:`Limited API`; its contents
|
||||
are :ref:`listed below <limited-api-list>`.
|
||||
|
||||
On Windows, extensions that use a Stable ABI should be linked against
|
||||
``python3.dll`` rather than a version-specific library such as
|
||||
``python39.dll``.
|
||||
This library only exposes the relevant symbols.
|
||||
|
||||
On some platforms, Python will look for and load shared library files named
|
||||
with the ``abi3`` tag (e.g. ``mymodule.abi3.so``).
|
||||
It does not check if such extensions conform to a Stable ABI.
|
||||
The user (or their packaging tools) need to ensure that, for example,
|
||||
extensions built with the 3.10+ Limited API are not installed for lower
|
||||
with the ``abi3`` or ``abi3t`` tag (for example, ``mymodule.abi3.so``).
|
||||
:term:`Free-threaded <free-threaded build>` interpreters only recognize the
|
||||
``abi3t`` tag, while non-free-threaded ones will prefer ``abi3`` but fall back
|
||||
to ``abi3t``.
|
||||
Thus, extensions compatible with both ABIs should use the ``abi3t`` tag.
|
||||
|
||||
Python does not necessarily check that extensions it loads
|
||||
have compatible ABI.
|
||||
Extension authors are encouraged to add a check using the :c:macro:`Py_mod_abi`
|
||||
slot or the :c:func:`PyABIInfo_Check` function, but the user
|
||||
(or their packaging tool) is ultimately responsible for ensuring that,
|
||||
for example, extensions built for Stable ABI 3.10 are not installed for lower
|
||||
versions of Python.
|
||||
|
||||
All functions in the Stable ABI are present as functions in Python's shared
|
||||
library, not solely as macros. This makes them usable from languages that don't
|
||||
use the C preprocessor.
|
||||
All functions in Stable ABI are present as functions in Python's shared
|
||||
library, not solely as macros.
|
||||
This makes them usable are usable from languages that don't use the C
|
||||
preprocessor, including Python's :py:mod:`ctypes`.
|
||||
|
||||
|
||||
Limited API Scope and Performance
|
||||
---------------------------------
|
||||
.. _abi3-compiling:
|
||||
|
||||
The goal for the Limited API is to allow everything that is possible with the
|
||||
Compiling for Stable ABI
|
||||
------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
Build tools (such as, for example, meson-python, scikit-build-core,
|
||||
or Setuptools) often have a mechanism for setting macros and synchronizing
|
||||
them with extension filenames and other metadata.
|
||||
Prefer using such a mechanism, if it exists, over defining the
|
||||
macros manually.
|
||||
|
||||
The rest of this section is mainly relevant for tool authors, and for
|
||||
people who compile extensions manually.
|
||||
|
||||
.. seealso:: `list of recommended tools`_ in the Python Packaging User Guide
|
||||
|
||||
.. _list of recommended tools: https://packaging.python.org/en/latest/guides/tool-recommendations/#build-backends-for-extension-modules
|
||||
|
||||
To compile for a Stable ABI, define one or both of the following macros
|
||||
to the lowest Python version your extension should support, in
|
||||
:c:macro:`Py_PACK_VERSION` format.
|
||||
Typically, you should choose a specific value rather than the version of
|
||||
the Python headers you are compiling against.
|
||||
|
||||
The macros must be defined before including ``Python.h``.
|
||||
Since :c:macro:`Py_PACK_VERSION` is not available at this point, you
|
||||
will need to use the numeric value directly.
|
||||
For reference, the values for a few recent Python versions are:
|
||||
|
||||
.. version-hex-cheatsheet::
|
||||
|
||||
When one of the macros is defined, ``Python.h`` will only expose API that is
|
||||
compatible with the given Stable ABI -- that is, the
|
||||
:ref:`Limited API <limited-api-list>` plus some definitions that need to be
|
||||
visible to the compiler but should not be used directly.
|
||||
When both are defined, ``Python.h`` will only expose API compatible with
|
||||
both Stable ABIs.
|
||||
|
||||
.. c:macro:: Py_LIMITED_API
|
||||
|
||||
Target ``abi3``, that is,
|
||||
non-:term:`free-threaded builds <free-threaded build>` of CPython.
|
||||
See :ref:`above <abi3-compiling>` for common information.
|
||||
|
||||
.. c:macro:: Py_TARGET_ABI3T
|
||||
|
||||
Target ``abi3t``, that is,
|
||||
:term:`free-threaded builds <free-threaded build>` of CPython.
|
||||
See :ref:`above <abi3-compiling>` for common information.
|
||||
|
||||
.. versionadded:: next
|
||||
|
||||
Both macros specify a target ABI; the different naming style is due to
|
||||
backwards compatibility.
|
||||
|
||||
.. admonition:: Historical note
|
||||
|
||||
You can also define ``Py_LIMITED_API`` as ``3``. This works the same as
|
||||
``0x03020000`` (Python 3.2, the version that introduced Stable ABI).
|
||||
|
||||
When both are defined, ``Python.h`` may, or may not, redefine
|
||||
:c:macro:`!Py_LIMITED_API` to match :c:macro:`!Py_TARGET_ABI3T`.
|
||||
|
||||
On a :term:`free-threaded build` -- that is, when
|
||||
:c:macro:`Py_GIL_DISABLED` is defined -- :c:macro:`!Py_TARGET_ABI3T`
|
||||
defaults to the value of :c:macro:`!Py_LIMITED_API`.
|
||||
This means that there are two ways to build for both ``abi3`` and ``abi3t``:
|
||||
|
||||
- define both :c:macro:`!Py_LIMITED_API` and :c:macro:`!Py_TARGET_ABI3T`, or
|
||||
- define only :c:macro:`!Py_LIMITED_API` and:
|
||||
|
||||
- on Windows, define :c:macro:`!Py_GIL_DISABLED`;
|
||||
- on other systems, use the headers of free-threaded build of Python.
|
||||
|
||||
|
||||
.. _limited-api-scope-and-performance:
|
||||
|
||||
Stable ABI Scope and Performance
|
||||
--------------------------------
|
||||
|
||||
The goal for Stable ABI is to allow everything that is possible with the
|
||||
full C API, but possibly with a performance penalty.
|
||||
Generally, compatibility with Stable ABI will require some changes to an
|
||||
extension's source code.
|
||||
|
||||
For example, while :c:func:`PyList_GetItem` is available, its “unsafe” macro
|
||||
For example, while :c:func:`PyList_GetItem` is available, its "unsafe" macro
|
||||
variant :c:func:`PyList_GET_ITEM` is not.
|
||||
The macro can be faster because it can rely on version-specific implementation
|
||||
details of the list object.
|
||||
|
||||
Without ``Py_LIMITED_API`` defined, some C API functions are inlined or
|
||||
replaced by macros.
|
||||
Defining ``Py_LIMITED_API`` disables this inlining, allowing stability as
|
||||
For another example, when *not* compiling for Stable ABI, some C API
|
||||
functions are inlined or replaced by macros.
|
||||
Compiling for Stable ABI disables this inlining, allowing stability as
|
||||
Python's data structures are improved, but possibly reducing performance.
|
||||
|
||||
By leaving out the ``Py_LIMITED_API`` definition, it is possible to compile
|
||||
a Limited API extension with a version-specific ABI. This can improve
|
||||
performance for that Python version, but will limit compatibility.
|
||||
Compiling with ``Py_LIMITED_API`` will then yield an extension that can be
|
||||
distributed where a version-specific one is not available – for example,
|
||||
for prereleases of an upcoming Python version.
|
||||
By leaving out the :c:macro:`!Py_LIMITED_API` or :c:macro:`!Py_TARGET_ABI3T`
|
||||
definition, it is possible to compile Stable-ABI-compatible source
|
||||
for a version-specific ABI.
|
||||
A potentially faster version-specific extension can then be distributed
|
||||
alongside a version compiled for Stable ABI -- a slower but more compatible
|
||||
fallback.
|
||||
|
||||
|
||||
Limited API Caveats
|
||||
-------------------
|
||||
.. _limited-api-caveats:
|
||||
|
||||
Note that compiling with ``Py_LIMITED_API`` is *not* a complete guarantee that
|
||||
code conforms to the :ref:`Limited API <limited-c-api>` or the :ref:`Stable ABI
|
||||
<stable-abi>`. ``Py_LIMITED_API`` only covers definitions, but an API also
|
||||
includes other issues, such as expected semantics.
|
||||
Stable ABI Caveats
|
||||
------------------
|
||||
|
||||
One issue that ``Py_LIMITED_API`` does not guard against is calling a function
|
||||
with arguments that are invalid in a lower Python version.
|
||||
Note that compiling for Stable ABI is *not* a complete guarantee that code will
|
||||
be compatible with the expected Python versions.
|
||||
Stable ABI prevents *ABI* issues, like linker errors due to missing
|
||||
symbols or data corruption due to changes in structure layouts or function
|
||||
signatures.
|
||||
However, other changes in Python can change the *behavior* of extensions.
|
||||
|
||||
One issue that the :c:macro:`Py_TARGET_ABI3T` and :c:macro:`Py_LIMITED_API`
|
||||
macros do not guard against is calling a function with arguments that are
|
||||
invalid in a lower Python version.
|
||||
For example, consider a function that starts accepting ``NULL`` for an
|
||||
argument. In Python 3.9, ``NULL`` now selects a default behavior, but in
|
||||
Python 3.8, the argument will be used directly, causing a ``NULL`` dereference
|
||||
and crash. A similar argument works for fields of structs.
|
||||
|
||||
Another issue is that some struct fields are currently not hidden when
|
||||
``Py_LIMITED_API`` is defined, even though they're part of the Limited API.
|
||||
|
||||
For these reasons, we recommend testing an extension with *all* minor Python
|
||||
versions it supports, and preferably to build with the *lowest* such version.
|
||||
versions it supports.
|
||||
|
||||
We also recommend reviewing documentation of all used API to check
|
||||
if it is explicitly part of the Limited API. Even with ``Py_LIMITED_API``
|
||||
defined, a few private declarations are exposed for technical reasons (or
|
||||
even unintentionally, as bugs).
|
||||
|
||||
Also note that the Limited API is not necessarily stable: compiling with
|
||||
``Py_LIMITED_API`` with Python 3.8 means that the extension will
|
||||
run with Python 3.12, but it will not necessarily *compile* with Python 3.12.
|
||||
In particular, parts of the Limited API may be deprecated and removed,
|
||||
provided that the Stable ABI stays stable.
|
||||
Also note that while compiling with ``Py_LIMITED_API`` 3.8 means that the
|
||||
extension should *load* on Python 3.12, and *compile* with Python 3.12,
|
||||
the same source will not necessarily compile with ``Py_LIMITED_API``
|
||||
set to 3.12.
|
||||
In general, parts of the Limited API may be deprecated and removed,
|
||||
provided that Stable ABI stays stable.
|
||||
|
||||
|
||||
.. _stable-abi-platform:
|
||||
|
|
@ -199,12 +266,12 @@ Platform Considerations
|
|||
|
||||
ABI stability depends not only on Python, but also on the compiler used,
|
||||
lower-level libraries and compiler options. For the purposes of
|
||||
the :ref:`Stable ABI <stable-abi>`, these details define a “platform”. They
|
||||
the :ref:`Stable ABIs <stable-abi>`, these details define a “platform”. They
|
||||
usually depend on the OS type and processor architecture
|
||||
|
||||
It is the responsibility of each particular distributor of Python
|
||||
to ensure that all Python versions on a particular platform are built
|
||||
in a way that does not break the Stable ABI.
|
||||
in a way that does not break the Stable ABIs, or the version-specific ABIs.
|
||||
This is the case with Windows and macOS releases from ``python.org`` and many
|
||||
third-party distributors.
|
||||
|
||||
|
|
@ -312,7 +379,7 @@ The full API is described below for advanced use cases.
|
|||
|
||||
.. c:macro:: PyABIInfo_STABLE
|
||||
|
||||
Specifies that the stable ABI is used.
|
||||
Specifies that Stable ABI is used.
|
||||
|
||||
.. c:macro:: PyABIInfo_INTERNAL
|
||||
|
||||
|
|
@ -323,15 +390,22 @@ The full API is described below for advanced use cases.
|
|||
|
||||
.. c:macro:: PyABIInfo_FREETHREADED
|
||||
|
||||
Specifies ABI compatible with free-threading builds of CPython.
|
||||
Specifies ABI compatible with :term:`free-threaded builds
|
||||
<free-threaded build>` of CPython.
|
||||
(That is, ones compiled with :option:`--disable-gil`; with ``t``
|
||||
in :py:data:`sys.abiflags`)
|
||||
|
||||
.. c:macro:: PyABIInfo_GIL
|
||||
|
||||
Specifies ABI compatible with non-free-threading builds of CPython
|
||||
Specifies ABI compatible with non-free-threaded builds of CPython
|
||||
(ones compiled *without* :option:`--disable-gil`).
|
||||
|
||||
.. c:macro:: PyABIInfo_FREETHREADING_AGNOSTIC
|
||||
|
||||
Specifies ABI compatible with both free-threaded and
|
||||
non-free-threaded builds of CPython, that is, both
|
||||
``abi3`` and ``abi3t``.
|
||||
|
||||
.. c:member:: uint32_t build_version
|
||||
|
||||
The version of the Python headers used to build the code, in the format
|
||||
|
|
@ -345,10 +419,11 @@ The full API is described below for advanced use cases.
|
|||
|
||||
The ABI version.
|
||||
|
||||
For the Stable ABI, this field should be the value of
|
||||
:c:macro:`Py_LIMITED_API`
|
||||
(except if :c:macro:`Py_LIMITED_API` is ``3``; use
|
||||
:c:expr:`Py_PACK_VERSION(3, 2)` in that case).
|
||||
For Stable ABI, this field should be the value of
|
||||
:c:macro:`Py_LIMITED_API` or :c:macro:`Py_TARGET_ABI3T`.
|
||||
If both are defined, use the smaller value.
|
||||
(If :c:macro:`Py_LIMITED_API` is ``3``; use
|
||||
:c:expr:`Py_PACK_VERSION(3, 2)` instead of ``3``.)
|
||||
|
||||
Otherwise, it should be set to :c:macro:`PY_VERSION_HEX`.
|
||||
|
||||
|
|
@ -365,12 +440,13 @@ The full API is described below for advanced use cases.
|
|||
.. versionadded:: 3.15
|
||||
|
||||
|
||||
.. _limited-c-api:
|
||||
.. _limited-api-list:
|
||||
|
||||
Contents of Limited API
|
||||
=======================
|
||||
|
||||
|
||||
Currently, the :ref:`Limited API <limited-c-api>` includes the following items:
|
||||
This is the definitive list of :ref:`Limited API <limited-c-api>` for
|
||||
Python |version|:
|
||||
|
||||
.. limited-api-list::
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@ under :ref:`reference counting <countingrefs>`.
|
|||
The members must not be accessed directly; instead use macros such as
|
||||
:c:macro:`Py_REFCNT` and :c:macro:`Py_TYPE`.
|
||||
|
||||
In the :ref:`Stable ABI <stable-abi>` for Free-Threaded Builds (``abi3t``),
|
||||
this struct is opaque; its size and layout may change between
|
||||
Python versions.
|
||||
In Stable ABI for non-free-threaded builds (``abi3``), the
|
||||
:c:member:`!ob_refcnt` and :c:member:`!ob_type` fields are available,
|
||||
but using them directly is discouraged.
|
||||
|
||||
.. c:member:: Py_ssize_t ob_refcnt
|
||||
|
||||
The object's reference count, as returned by :c:macro:`Py_REFCNT`.
|
||||
|
|
@ -72,6 +79,19 @@ under :ref:`reference counting <countingrefs>`.
|
|||
instead use macros such as :c:macro:`Py_SIZE`, :c:macro:`Py_REFCNT` and
|
||||
:c:macro:`Py_TYPE`.
|
||||
|
||||
In the :ref:`Stable ABI <stable-abi>` for Free-Threaded Builds (``abi3t``),
|
||||
this struct is opaque; its size and layout may change between
|
||||
Python versions.
|
||||
In Stable ABI for non-free-threaded builds (``abi3``), the
|
||||
:c:member:`!ob_base` and :c:member:`!ob_size` fields are available,
|
||||
but using them directly is discouraged.
|
||||
|
||||
.. c:member:: PyObject ob_base
|
||||
|
||||
Common object header.
|
||||
Typically, this field is not accessed directly; instead
|
||||
:c:type:`!PyVarObject` can be cast to :c:type:`PyObject`.
|
||||
|
||||
.. c:member:: Py_ssize_t ob_size
|
||||
|
||||
A size field, whose contents should be considered an object's internal
|
||||
|
|
|
|||
|
|
@ -399,6 +399,27 @@ High-level APIs
|
|||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. c:function:: void _PyInterpreterState_SetEvalFrameAllowSpecialization(PyInterpreterState *interp, int allow_specialization)
|
||||
|
||||
Enables or disables specialization why a custom frame evaluator is in place.
|
||||
|
||||
If *allow_specialization* is non-zero, the adaptive specializer will
|
||||
continue to specialize bytecodes even though a custom eval frame function
|
||||
is set. When *allow_specialization* is zero, setting a custom eval frame
|
||||
disables specialization. The standard interpreter loop will continue to deopt
|
||||
while a frame evaluation API is in place - the frame evaluation function needs
|
||||
to handle the specialized opcodes to take advantage of this.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. c:function:: int _PyInterpreterState_IsSpecializationEnabled(PyInterpreterState *interp)
|
||||
|
||||
Return non-zero if adaptive specialization is enabled for the interpreter.
|
||||
Specialization is enabled when no custom eval frame function is set, or
|
||||
when one is set with *allow_specialization* enabled.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
|
||||
Low-level APIs
|
||||
--------------
|
||||
|
|
|
|||
|
|
@ -1391,8 +1391,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
|||
|
||||
.. versionchanged:: 3.9
|
||||
|
||||
Renamed to the current name, without the leading underscore.
|
||||
The old provisional name is :term:`soft deprecated`.
|
||||
Renamed to the current name, without the leading underscore.
|
||||
The old provisional name is :term:`soft deprecated`.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
|
|
@ -1501,11 +1501,13 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
|||
|
||||
.. c:macro:: Py_TPFLAGS_HAVE_VERSION_TAG
|
||||
|
||||
This is a :term:`soft deprecated` macro that does nothing.
|
||||
This macro does nothing.
|
||||
Historically, this would indicate that the
|
||||
:c:member:`~PyTypeObject.tp_version_tag` field was available and
|
||||
initialized.
|
||||
|
||||
.. soft-deprecated:: 3.13
|
||||
|
||||
|
||||
.. c:macro:: Py_TPFLAGS_INLINE_VALUES
|
||||
|
||||
|
|
|
|||
4
Doc/data/stable_abi.dat
generated
4
Doc/data/stable_abi.dat
generated
|
|
@ -470,8 +470,8 @@ func,PyMemoryView_GetContiguous,3.2,,
|
|||
data,PyMemoryView_Type,3.2,,
|
||||
type,PyMethodDef,3.2,,full-abi
|
||||
data,PyMethodDescr_Type,3.2,,
|
||||
type,PyModuleDef,3.2,,full-abi
|
||||
type,PyModuleDef_Base,3.2,,full-abi
|
||||
type,PyModuleDef,3.2,,abi3t-opaque
|
||||
type,PyModuleDef_Base,3.2,,abi3t-opaque
|
||||
func,PyModuleDef_Init,3.5,,
|
||||
type,PyModuleDef_Slot,3.5,,full-abi
|
||||
data,PyModuleDef_Type,3.5,,
|
||||
|
|
|
|||
|
|
@ -14,10 +14,71 @@
|
|||
# The function name must match the C domain identifier used in the documentation.
|
||||
|
||||
# Synchronization primitives (Doc/c-api/synchronization.rst)
|
||||
PyMutex_Lock:shared:
|
||||
PyMutex_Unlock:shared:
|
||||
PyMutex_Lock:atomic:
|
||||
PyMutex_Unlock:atomic:
|
||||
PyMutex_IsLocked:atomic:
|
||||
|
||||
|
||||
# Dictionary objects (Doc/c-api/dict.rst)
|
||||
|
||||
# Type checks - read ob_type pointer, always safe
|
||||
PyDict_Check:atomic:
|
||||
PyDict_CheckExact:atomic:
|
||||
|
||||
# Creation - pure allocation, no shared state
|
||||
PyDict_New:atomic:
|
||||
|
||||
# Lock-free lookups - use _Py_dict_lookup_threadsafe(), no locking.
|
||||
# Atomic with simple types.
|
||||
PyDict_Contains:shared:
|
||||
PyDict_ContainsString:atomic:
|
||||
PyDict_GetItemRef:shared:
|
||||
PyDict_GetItemStringRef:atomic:
|
||||
PyDict_Size:atomic:
|
||||
PyDict_GET_SIZE:atomic:
|
||||
|
||||
# Borrowed-reference lookups - lock-free dict access but returned
|
||||
# borrowed reference is unsafe in free-threaded builds without
|
||||
# external synchronization
|
||||
PyDict_GetItem:compatible:
|
||||
PyDict_GetItemWithError:compatible:
|
||||
PyDict_GetItemString:compatible:
|
||||
PyDict_SetDefault:compatible:
|
||||
|
||||
# Iteration - no locking; returns borrowed refs
|
||||
PyDict_Next:compatible:
|
||||
|
||||
# Single-item mutations - protected by per-object critical section
|
||||
PyDict_SetItem:shared:
|
||||
PyDict_SetItemString:atomic:
|
||||
PyDict_DelItem:shared:
|
||||
PyDict_DelItemString:atomic:
|
||||
PyDict_SetDefaultRef:shared:
|
||||
PyDict_Pop:shared:
|
||||
PyDict_PopString:atomic:
|
||||
|
||||
# Bulk reads - hold per-object lock for duration
|
||||
PyDict_Clear:atomic:
|
||||
PyDict_Copy:atomic:
|
||||
PyDict_Keys:atomic:
|
||||
PyDict_Values:atomic:
|
||||
PyDict_Items:atomic:
|
||||
|
||||
# Merge/update - lock target dict; also lock source when it is a dict
|
||||
PyDict_Update:shared:
|
||||
PyDict_Merge:shared:
|
||||
PyDict_MergeFromSeq2:shared:
|
||||
|
||||
# Watcher registration - no synchronization on interpreter state
|
||||
PyDict_AddWatcher:compatible:
|
||||
PyDict_ClearWatcher:compatible:
|
||||
|
||||
# Per-dict watcher tags - non-atomic RMW on _ma_watcher_tag;
|
||||
# safe on distinct dicts only
|
||||
PyDict_Watch:distinct:
|
||||
PyDict_Unwatch:distinct:
|
||||
|
||||
|
||||
# List objects (Doc/c-api/list.rst)
|
||||
|
||||
# Type checks - read ob_type pointer, always safe
|
||||
|
|
@ -125,6 +186,29 @@ PyByteArray_GET_SIZE:atomic:
|
|||
PyByteArray_AsString:compatible:
|
||||
PyByteArray_AS_STRING:compatible:
|
||||
|
||||
# Creation - may iterate the iterable argument, calling arbitrary code.
|
||||
# Atomic for sets, frozensets, dicts, and frozendicts.
|
||||
PySet_New:shared:
|
||||
PyFrozenSet_New:shared:
|
||||
|
||||
# Size - uses atomic load on free-threaded builds
|
||||
PySet_Size:atomic:
|
||||
PySet_GET_SIZE:atomic:
|
||||
|
||||
# Contains - lock-free, atomic with simple types
|
||||
PySet_Contains:shared:
|
||||
|
||||
# Mutations - hold per-object lock for duration
|
||||
# atomic with simple types
|
||||
PySet_Add:shared:
|
||||
PySet_Discard:shared:
|
||||
|
||||
# Pop - hold per-object lock for duration
|
||||
PySet_Pop:atomic:
|
||||
|
||||
# Clear - empties the set before clearing
|
||||
PySet_Clear:atomic:
|
||||
|
||||
# Capsule objects (Doc/c-api/capsule.rst)
|
||||
|
||||
# Type check - read ob_type pointer, always safe
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ Deprecations
|
|||
|
||||
.. include:: pending-removal-in-future.rst
|
||||
|
||||
.. include:: soft-deprecations.rst
|
||||
|
||||
C API deprecations
|
||||
------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Pending removal in Python 3.15
|
|||
|
||||
* :mod:`types`:
|
||||
|
||||
* :class:`types.CodeType`: Accessing :attr:`~codeobject.co_lnotab` was
|
||||
* :class:`types.CodeType`: Accessing :attr:`!codeobject.co_lnotab` was
|
||||
deprecated in :pep:`626`
|
||||
since 3.10 and was planned to be removed in 3.12,
|
||||
but it only got a proper :exc:`DeprecationWarning` in 3.12.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
Pending removal in Python 3.17
|
||||
------------------------------
|
||||
|
||||
* :mod:`datetime`:
|
||||
|
||||
* :meth:`~datetime.datetime.strptime` calls using a format string containing
|
||||
``%e`` (day of month) without a year.
|
||||
This has been deprecated since Python 3.15.
|
||||
(Contributed by Stan Ulbrych in :gh:`70647`.)
|
||||
|
||||
|
||||
* :mod:`collections.abc`:
|
||||
|
||||
- :class:`collections.abc.ByteString` is scheduled for removal in Python 3.17.
|
||||
|
|
@ -27,7 +35,7 @@ Pending removal in Python 3.17
|
|||
|
||||
- Passing non-ascii *encoding* names to :func:`encodings.normalize_encoding`
|
||||
is deprecated and scheduled for removal in Python 3.17.
|
||||
(Contributed by Stan Ulbrych in :gh:`136702`)
|
||||
(Contributed by Stan Ulbrych in :gh:`136702`.)
|
||||
|
||||
* :mod:`typing`:
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ although there is currently no date scheduled for their removal.
|
|||
|
||||
* :mod:`codecs`: use :func:`open` instead of :func:`codecs.open`. (:gh:`133038`)
|
||||
|
||||
* :attr:`codeobject.co_lnotab`: use the :meth:`codeobject.co_lines` method
|
||||
* :attr:`!codeobject.co_lnotab`: use the :meth:`codeobject.co_lines` method
|
||||
instead.
|
||||
|
||||
* :mod:`datetime`:
|
||||
|
|
|
|||
21
Doc/deprecations/soft-deprecations.rst
Normal file
21
Doc/deprecations/soft-deprecations.rst
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Soft deprecations
|
||||
-----------------
|
||||
|
||||
There are no plans to remove :term:`soft deprecated` APIs.
|
||||
|
||||
* :func:`re.match` and :meth:`re.Pattern.match` are now
|
||||
:term:`soft deprecated` in favor of the new :func:`re.prefixmatch` and
|
||||
:meth:`re.Pattern.prefixmatch` APIs, which have been added as alternate,
|
||||
more explicit names. These are intended to be used to alleviate confusion
|
||||
around what *match* means by following the Zen of Python's *"Explicit is
|
||||
better than implicit"* mantra. Most other language regular expression
|
||||
libraries use an API named *match* to mean what Python has always called
|
||||
*search*.
|
||||
|
||||
We **do not** plan to remove the older :func:`!match` name, as it has been
|
||||
used in code for over 30 years. Code supporting older versions of Python
|
||||
should continue to use :func:`!match`, while new code should prefer
|
||||
:func:`!prefixmatch`. See :ref:`prefixmatch-vs-match`.
|
||||
|
||||
(Contributed by Gregory P. Smith in :gh:`86519` and
|
||||
Hugo van Kemenade in :gh:`148100`.)
|
||||
|
|
@ -371,7 +371,7 @@ Equality comparisons are defined though::
|
|||
>>> Color.BLUE == Color.BLUE
|
||||
True
|
||||
|
||||
Comparisons against non-enumeration values will always compare not equal
|
||||
Equality comparisons against non-enumeration values will always return ``False``
|
||||
(again, :class:`IntEnum` was explicitly designed to behave differently, see
|
||||
below)::
|
||||
|
||||
|
|
|
|||
|
|
@ -416,11 +416,9 @@ C API extensions need to be built specifically for the free-threaded build.
|
|||
The wheels, shared libraries, and binaries are indicated by a ``t`` suffix.
|
||||
|
||||
* `pypa/manylinux <https://github.com/pypa/manylinux>`_ supports the
|
||||
free-threaded build, with the ``t`` suffix, such as ``python3.13t``.
|
||||
* `pypa/cibuildwheel <https://github.com/pypa/cibuildwheel>`_ supports the
|
||||
free-threaded build on Python 3.13 and 3.14. On Python 3.14, free-threaded
|
||||
wheels will be built by default. On Python 3.13, you will need to set
|
||||
`CIBW_ENABLE to cpython-freethreading <https://cibuildwheel.pypa.io/en/stable/options/#enable>`_.
|
||||
free-threaded build, with the ``t`` suffix, such as ``python3.14t``.
|
||||
* `pypa/cibuildwheel <https://github.com/pypa/cibuildwheel>`_ supports
|
||||
building wheels for the free-threaded build of Python 3.14 and newer.
|
||||
|
||||
Limited C API and Stable ABI
|
||||
............................
|
||||
|
|
|
|||
|
|
@ -3877,7 +3877,7 @@ subclassed handler which looks something like this::
|
|||
def format(self, record):
|
||||
version = 1
|
||||
asctime = dt.datetime.fromtimestamp(record.created).isoformat()
|
||||
m = self.tz_offset.match(time.strftime('%z'))
|
||||
m = self.tz_offset.prefixmatch(time.strftime('%z'))
|
||||
has_offset = False
|
||||
if m and time.timezone:
|
||||
hrs, mins = m.groups()
|
||||
|
|
|
|||
|
|
@ -362,12 +362,13 @@ for a complete listing.
|
|||
+------------------+-----------------------------------------------+
|
||||
| Method/Attribute | Purpose |
|
||||
+==================+===============================================+
|
||||
| ``match()`` | Determine if the RE matches at the beginning |
|
||||
| | of the string. |
|
||||
+------------------+-----------------------------------------------+
|
||||
| ``search()`` | Scan through a string, looking for any |
|
||||
| | location where this RE matches. |
|
||||
+------------------+-----------------------------------------------+
|
||||
| ``prefixmatch()``| Determine if the RE matches at the beginning |
|
||||
| | of the string. Previously named :ref:`match() |
|
||||
| | <prefixmatch-vs-match>`. |
|
||||
+------------------+-----------------------------------------------+
|
||||
| ``findall()`` | Find all substrings where the RE matches, and |
|
||||
| | return them as a list. |
|
||||
+------------------+-----------------------------------------------+
|
||||
|
|
@ -375,7 +376,7 @@ for a complete listing.
|
|||
| | return them as an :term:`iterator`. |
|
||||
+------------------+-----------------------------------------------+
|
||||
|
||||
:meth:`~re.Pattern.match` and :meth:`~re.Pattern.search` return ``None`` if no match can be found. If
|
||||
:meth:`~re.Pattern.search` and :meth:`~re.Pattern.prefixmatch` return ``None`` if no match can be found. If
|
||||
they're successful, a :ref:`match object <match-objects>` instance is returned,
|
||||
containing information about the match: where it starts and ends, the substring
|
||||
it matched, and more.
|
||||
|
|
@ -393,19 +394,19 @@ Python interpreter, import the :mod:`re` module, and compile a RE::
|
|||
|
||||
Now, you can try matching various strings against the RE ``[a-z]+``. An empty
|
||||
string shouldn't match at all, since ``+`` means 'one or more repetitions'.
|
||||
:meth:`~re.Pattern.match` should return ``None`` in this case, which will cause the
|
||||
:meth:`~re.Pattern.search` should return ``None`` in this case, which will cause the
|
||||
interpreter to print no output. You can explicitly print the result of
|
||||
:meth:`!match` to make this clear. ::
|
||||
:meth:`!search` to make this clear. ::
|
||||
|
||||
>>> p.match("")
|
||||
>>> print(p.match(""))
|
||||
>>> p.search("")
|
||||
>>> print(p.search(""))
|
||||
None
|
||||
|
||||
Now, let's try it on a string that it should match, such as ``tempo``. In this
|
||||
case, :meth:`~re.Pattern.match` will return a :ref:`match object <match-objects>`, so you
|
||||
case, :meth:`~re.Pattern.search` will return a :ref:`match object <match-objects>`, so you
|
||||
should store the result in a variable for later use. ::
|
||||
|
||||
>>> m = p.match('tempo')
|
||||
>>> m = p.search('tempo')
|
||||
>>> m
|
||||
<re.Match object; span=(0, 5), match='tempo'>
|
||||
|
||||
|
|
@ -437,27 +438,28 @@ Trying these methods will soon clarify their meaning::
|
|||
|
||||
:meth:`~re.Match.group` returns the substring that was matched by the RE. :meth:`~re.Match.start`
|
||||
and :meth:`~re.Match.end` return the starting and ending index of the match. :meth:`~re.Match.span`
|
||||
returns both start and end indexes in a single tuple. Since the :meth:`~re.Pattern.match`
|
||||
method only checks if the RE matches at the start of a string, :meth:`!start`
|
||||
will always be zero. However, the :meth:`~re.Pattern.search` method of patterns
|
||||
scans through the string, so the match may not start at zero in that
|
||||
case. ::
|
||||
returns both start and end indexes in a single tuple.
|
||||
The :meth:`~re.Pattern.search` method of patterns
|
||||
scans through the string, so the match may not start at zero.
|
||||
However, the :meth:`~re.Pattern.prefixmatch`
|
||||
method only checks if the RE matches at the start of a string, so :meth:`!start`
|
||||
will always be zero in that case. ::
|
||||
|
||||
>>> print(p.match('::: message'))
|
||||
None
|
||||
>>> m = p.search('::: message'); print(m)
|
||||
<re.Match object; span=(4, 11), match='message'>
|
||||
>>> m.group()
|
||||
'message'
|
||||
>>> m.span()
|
||||
(4, 11)
|
||||
>>> print(p.prefixmatch('::: message'))
|
||||
None
|
||||
|
||||
In actual programs, the most common style is to store the
|
||||
:ref:`match object <match-objects>` in a variable, and then check if it was
|
||||
``None``. This usually looks like::
|
||||
|
||||
p = re.compile( ... )
|
||||
m = p.match( 'string goes here' )
|
||||
m = p.search( 'string goes here' )
|
||||
if m:
|
||||
print('Match found: ', m.group())
|
||||
else:
|
||||
|
|
@ -495,15 +497,15 @@ Module-level functions
|
|||
----------------------
|
||||
|
||||
You don't have to create a pattern object and call its methods; the
|
||||
:mod:`re` module also provides top-level functions called :func:`~re.match`,
|
||||
:func:`~re.search`, :func:`~re.findall`, :func:`~re.sub`, and so forth. These functions
|
||||
:mod:`re` module also provides top-level functions called :func:`~re.search`,
|
||||
:func:`~re.prefixmatch`, :func:`~re.findall`, :func:`~re.sub`, and so forth. These functions
|
||||
take the same arguments as the corresponding pattern method with
|
||||
the RE string added as the first argument, and still return either ``None`` or a
|
||||
:ref:`match object <match-objects>` instance. ::
|
||||
|
||||
>>> print(re.match(r'From\s+', 'Fromage amk'))
|
||||
>>> print(re.prefixmatch(r'From\s+', 'Fromage amk'))
|
||||
None
|
||||
>>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998') #doctest: +ELLIPSIS
|
||||
>>> re.prefixmatch(r'From\s+', 'From amk Thu May 14 19:12:10 1998') #doctest: +ELLIPSIS
|
||||
<re.Match object; span=(0, 5), match='From '>
|
||||
|
||||
Under the hood, these functions simply create a pattern object for you
|
||||
|
|
@ -812,7 +814,7 @@ of a group with a quantifier, such as ``*``, ``+``, ``?``, or
|
|||
``ab``. ::
|
||||
|
||||
>>> p = re.compile('(ab)*')
|
||||
>>> print(p.match('ababababab').span())
|
||||
>>> print(p.search('ababababab').span())
|
||||
(0, 10)
|
||||
|
||||
Groups indicated with ``'('``, ``')'`` also capture the starting and ending
|
||||
|
|
@ -825,7 +827,7 @@ argument. Later we'll see how to express groups that don't capture the span
|
|||
of text that they match. ::
|
||||
|
||||
>>> p = re.compile('(a)b')
|
||||
>>> m = p.match('ab')
|
||||
>>> m = p.search('ab')
|
||||
>>> m.group()
|
||||
'ab'
|
||||
>>> m.group(0)
|
||||
|
|
@ -836,7 +838,7 @@ to determine the number, just count the opening parenthesis characters, going
|
|||
from left to right. ::
|
||||
|
||||
>>> p = re.compile('(a(b)c)d')
|
||||
>>> m = p.match('abcd')
|
||||
>>> m = p.search('abcd')
|
||||
>>> m.group(0)
|
||||
'abcd'
|
||||
>>> m.group(1)
|
||||
|
|
@ -912,10 +914,10 @@ but aren't interested in retrieving the group's contents. You can make this fact
|
|||
explicit by using a non-capturing group: ``(?:...)``, where you can replace the
|
||||
``...`` with any other regular expression. ::
|
||||
|
||||
>>> m = re.match("([abc])+", "abc")
|
||||
>>> m = re.search("([abc])+", "abc")
|
||||
>>> m.groups()
|
||||
('c',)
|
||||
>>> m = re.match("(?:[abc])+", "abc")
|
||||
>>> m = re.search("(?:[abc])+", "abc")
|
||||
>>> m.groups()
|
||||
()
|
||||
|
||||
|
|
@ -949,7 +951,7 @@ given numbers, so you can retrieve information about a group in two ways::
|
|||
Additionally, you can retrieve named groups as a dictionary with
|
||||
:meth:`~re.Match.groupdict`::
|
||||
|
||||
>>> m = re.match(r'(?P<first>\w+) (?P<last>\w+)', 'Jane Doe')
|
||||
>>> m = re.search(r'(?P<first>\w+) (?P<last>\w+)', 'Jane Doe')
|
||||
>>> m.groupdict()
|
||||
{'first': 'Jane', 'last': 'Doe'}
|
||||
|
||||
|
|
@ -1274,21 +1276,26 @@ In short, before turning to the :mod:`re` module, consider whether your problem
|
|||
can be solved with a faster and simpler string method.
|
||||
|
||||
|
||||
match() versus search()
|
||||
-----------------------
|
||||
.. _match-versus-search:
|
||||
|
||||
The :func:`~re.match` function only checks if the RE matches at the beginning of the
|
||||
string while :func:`~re.search` will scan forward through the string for a match.
|
||||
It's important to keep this distinction in mind. Remember, :func:`!match` will
|
||||
only report a successful match which will start at 0; if the match wouldn't
|
||||
start at zero, :func:`!match` will *not* report it. ::
|
||||
prefixmatch() (aka match) versus search()
|
||||
-----------------------------------------
|
||||
|
||||
>>> print(re.match('super', 'superstition').span())
|
||||
:func:`~re.prefixmatch` was added in Python 3.15 as the :ref:`preferred name
|
||||
<prefixmatch-vs-match>` for :func:`~re.match`. Before this, it was only known
|
||||
as :func:`!match` and the distinction with :func:`~re.search` was often
|
||||
misunderstood.
|
||||
|
||||
:func:`!prefixmatch` aka :func:`!match` only checks if the RE matches at the
|
||||
beginning of the string while :func:`!search` scans forward through the
|
||||
string for a match. ::
|
||||
|
||||
>>> print(re.prefixmatch('super', 'superstition').span())
|
||||
(0, 5)
|
||||
>>> print(re.match('super', 'insuperable'))
|
||||
>>> print(re.prefixmatch('super', 'insuperable'))
|
||||
None
|
||||
|
||||
On the other hand, :func:`~re.search` will scan forward through the string,
|
||||
On the other hand, :func:`~re.search` scans forward through the string,
|
||||
reporting the first match it finds. ::
|
||||
|
||||
>>> print(re.search('super', 'superstition').span())
|
||||
|
|
@ -1296,18 +1303,8 @@ reporting the first match it finds. ::
|
|||
>>> print(re.search('super', 'insuperable').span())
|
||||
(2, 7)
|
||||
|
||||
Sometimes you'll be tempted to keep using :func:`re.match`, and just add ``.*``
|
||||
to the front of your RE. Resist this temptation and use :func:`re.search`
|
||||
instead. The regular expression compiler does some analysis of REs in order to
|
||||
speed up the process of looking for a match. One such analysis figures out what
|
||||
the first character of a match must be; for example, a pattern starting with
|
||||
``Crow`` must match starting with a ``'C'``. The analysis lets the engine
|
||||
quickly scan through the string looking for the starting character, only trying
|
||||
the full match if a ``'C'`` is found.
|
||||
|
||||
Adding ``.*`` defeats this optimization, requiring scanning to the end of the
|
||||
string and then backtracking to find a match for the rest of the RE. Use
|
||||
:func:`re.search` instead.
|
||||
This distinction is important to remember when using the old :func:`~re.match`
|
||||
name in code requiring compatibility with older Python versions.
|
||||
|
||||
|
||||
Greedy versus non-greedy
|
||||
|
|
@ -1322,9 +1319,9 @@ doesn't work because of the greedy nature of ``.*``. ::
|
|||
>>> s = '<html><head><title>Title</title>'
|
||||
>>> len(s)
|
||||
32
|
||||
>>> print(re.match('<.*>', s).span())
|
||||
>>> print(re.prefixmatch('<.*>', s).span())
|
||||
(0, 32)
|
||||
>>> print(re.match('<.*>', s).group())
|
||||
>>> print(re.prefixmatch('<.*>', s).group())
|
||||
<html><head><title>Title</title>
|
||||
|
||||
The RE matches the ``'<'`` in ``'<html>'``, and the ``.*`` consumes the rest of
|
||||
|
|
@ -1340,7 +1337,7 @@ example, the ``'>'`` is tried immediately after the first ``'<'`` matches, and
|
|||
when it fails, the engine advances a character at a time, retrying the ``'>'``
|
||||
at every step. This produces just the right result::
|
||||
|
||||
>>> print(re.match('<.*?>', s).group())
|
||||
>>> print(re.prefixmatch('<.*?>', s).group())
|
||||
<html>
|
||||
|
||||
(Note that parsing HTML or XML with regular expressions is painful.
|
||||
|
|
|
|||
|
|
@ -1970,7 +1970,7 @@ FileType objects
|
|||
run and then use the :keyword:`with`-statement to manage the files.
|
||||
|
||||
.. versionchanged:: 3.4
|
||||
Added the *encodings* and *errors* parameters.
|
||||
Added the *encoding* and *errors* parameters.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
|
||||
|
|
@ -2032,6 +2032,9 @@ Argument groups
|
|||
Note that any arguments not in your user-defined groups will end up back
|
||||
in the usual "positional arguments" and "optional arguments" sections.
|
||||
|
||||
Within each argument group, arguments are displayed in help output in the
|
||||
order in which they are added.
|
||||
|
||||
.. deprecated-removed:: 3.11 3.14
|
||||
Calling :meth:`add_argument_group` on an argument group now raises an
|
||||
exception. This nesting was never supported, often failed to work
|
||||
|
|
|
|||
|
|
@ -2480,7 +2480,7 @@ and classes for traversing abstract syntax trees:
|
|||
node = YourTransformer().visit(node)
|
||||
|
||||
|
||||
.. function:: dump(node, annotate_fields=True, include_attributes=False, *, indent=None, show_empty=False)
|
||||
.. function:: dump(node, annotate_fields=True, include_attributes=False, *, color=False, indent=None, show_empty=False)
|
||||
|
||||
Return a formatted dump of the tree in *node*. This is mainly useful for
|
||||
debugging purposes. If *annotate_fields* is true (by default),
|
||||
|
|
@ -2490,6 +2490,10 @@ and classes for traversing abstract syntax trees:
|
|||
numbers and column offsets are not dumped by default. If this is wanted,
|
||||
*include_attributes* can be set to true.
|
||||
|
||||
If *color* is ``True``, the returned string is syntax highlighted using
|
||||
ANSI escape sequences.
|
||||
If ``False`` (the default), colored output is always disabled.
|
||||
|
||||
If *indent* is a non-negative integer or string, then the tree will be
|
||||
pretty-printed with that indent level. An indent level
|
||||
of 0, negative, or ``""`` will only insert newlines. ``None`` (the default)
|
||||
|
|
@ -2527,6 +2531,9 @@ and classes for traversing abstract syntax trees:
|
|||
.. versionchanged:: 3.15
|
||||
Omit optional ``Load()`` values by default.
|
||||
|
||||
.. versionchanged:: next
|
||||
Added the *color* parameter.
|
||||
|
||||
|
||||
.. _ast-compiler-flags:
|
||||
|
||||
|
|
@ -2584,6 +2591,10 @@ Command-line usage
|
|||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. versionchanged:: next
|
||||
The output is now syntax highlighted by default. This can be
|
||||
:ref:`controlled using environment variables <using-on-controlling-color>`.
|
||||
|
||||
The :mod:`!ast` module can be executed as a script from the command line.
|
||||
It is as simple as:
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ generator can occur in an unexpected order::
|
|||
try:
|
||||
yield 2
|
||||
finally:
|
||||
await asyncio.sleep(0.1) # immitate some async work
|
||||
await asyncio.sleep(0.1) # imitate some async work
|
||||
work_done = True
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -355,6 +355,34 @@ and reliable way to wait for all tasks in the group to finish.
|
|||
|
||||
Passes on all *kwargs* to :meth:`loop.create_task`
|
||||
|
||||
.. method:: cancel()
|
||||
|
||||
Cancel the task group. This is a non-exceptional, early exit of the
|
||||
task group's lifetime -- useful once the group's goal has been met or
|
||||
its services no longer needed.
|
||||
|
||||
:meth:`~asyncio.Task.cancel` will be called on any tasks in the group that
|
||||
aren't yet done, as well as the parent (body) of the group. The task group
|
||||
context manager will exit *without* :exc:`asyncio.CancelledError` being raised.
|
||||
|
||||
If :meth:`cancel` is called before entering the task group, the group will be
|
||||
cancelled upon entry. This is useful for patterns where one piece of
|
||||
code passes an unused :class:`asyncio.TaskGroup` instance to another in order to have
|
||||
the ability to cancel anything run within the group.
|
||||
|
||||
:meth:`cancel` is idempotent and may be called after the task group has
|
||||
already exited.
|
||||
|
||||
Some ways to use :meth:`cancel`:
|
||||
|
||||
* call it from the task group body based on some condition or event
|
||||
* pass the task group instance to child tasks via :meth:`create_task`, allowing a child
|
||||
task to conditionally cancel the entire entire group
|
||||
* pass the task group instance or bound :meth:`cancel` method to some other task *before*
|
||||
opening the task group, allowing remote cancellation
|
||||
|
||||
.. versionadded:: next
|
||||
|
||||
Example::
|
||||
|
||||
async def main():
|
||||
|
|
@ -366,7 +394,8 @@ Example::
|
|||
The ``async with`` statement will wait for all tasks in the group to finish.
|
||||
While waiting, new tasks may still be added to the group
|
||||
(for example, by passing ``tg`` into one of the coroutines
|
||||
and calling ``tg.create_task()`` in that coroutine).
|
||||
and calling ``tg.create_task()`` in that coroutine). There is also opportunity
|
||||
to short-circuit the entire task group with ``tg.cancel()``, based on some condition.
|
||||
Once the last task has finished and the ``async with`` block is exited,
|
||||
no new tasks may be added to the group.
|
||||
|
||||
|
|
@ -427,53 +456,6 @@ reported by :meth:`asyncio.Task.cancelling`.
|
|||
Improved handling of simultaneous internal and external cancellations
|
||||
and correct preservation of cancellation counts.
|
||||
|
||||
Terminating a task group
|
||||
------------------------
|
||||
|
||||
While terminating a task group is not natively supported by the standard
|
||||
library, termination can be achieved by adding an exception-raising task
|
||||
to the task group and ignoring the raised exception:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import asyncio
|
||||
from asyncio import TaskGroup
|
||||
|
||||
class TerminateTaskGroup(Exception):
|
||||
"""Exception raised to terminate a task group."""
|
||||
|
||||
async def force_terminate_task_group():
|
||||
"""Used to force termination of a task group."""
|
||||
raise TerminateTaskGroup()
|
||||
|
||||
async def job(task_id, sleep_time):
|
||||
print(f'Task {task_id}: start')
|
||||
await asyncio.sleep(sleep_time)
|
||||
print(f'Task {task_id}: done')
|
||||
|
||||
async def main():
|
||||
try:
|
||||
async with TaskGroup() as group:
|
||||
# spawn some tasks
|
||||
group.create_task(job(1, 0.5))
|
||||
group.create_task(job(2, 1.5))
|
||||
# sleep for 1 second
|
||||
await asyncio.sleep(1)
|
||||
# add an exception-raising task to force the group to terminate
|
||||
group.create_task(force_terminate_task_group())
|
||||
except* TerminateTaskGroup:
|
||||
pass
|
||||
|
||||
asyncio.run(main())
|
||||
|
||||
Expected output:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Task 1: start
|
||||
Task 2: start
|
||||
Task 1: done
|
||||
|
||||
Sleeping
|
||||
========
|
||||
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ POST request.
|
|||
Added the *padded* and *wrapcol* parameters.
|
||||
|
||||
|
||||
.. function:: b64decode(s, altchars=None, validate=False, *, padded=True)
|
||||
b64decode(s, altchars=None, validate=True, *, ignorechars, padded=True)
|
||||
.. function:: b64decode(s, altchars=None, validate=False, *, padded=True, canonical=False)
|
||||
b64decode(s, altchars=None, validate=True, *, ignorechars, padded=True, canonical=False)
|
||||
|
||||
Decode the Base64 encoded :term:`bytes-like object` or ASCII string
|
||||
*s* and return the decoded :class:`bytes`.
|
||||
|
|
@ -112,10 +112,13 @@ POST request.
|
|||
If *validate* is true, these non-alphabet characters in the input
|
||||
result in a :exc:`binascii.Error`.
|
||||
|
||||
If *canonical* is true, non-zero padding bits are rejected.
|
||||
See :func:`binascii.a2b_base64` for details.
|
||||
|
||||
For more information about the strict base64 check, see :func:`binascii.a2b_base64`
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Added the *ignorechars* and *padded* parameters.
|
||||
Added the *canonical*, *ignorechars*, and *padded* parameters.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
Accepting the ``+`` and ``/`` characters with an alternative alphabet
|
||||
|
|
@ -179,7 +182,7 @@ POST request.
|
|||
Added the *padded* and *wrapcol* parameters.
|
||||
|
||||
|
||||
.. function:: b32decode(s, casefold=False, map01=None, *, padded=True, ignorechars=b'')
|
||||
.. function:: b32decode(s, casefold=False, map01=None, *, padded=True, ignorechars=b'', canonical=False)
|
||||
|
||||
Decode the Base32 encoded :term:`bytes-like object` or ASCII string *s* and
|
||||
return the decoded :class:`bytes`.
|
||||
|
|
@ -205,12 +208,15 @@ POST request.
|
|||
*ignorechars* should be a :term:`bytes-like object` containing characters
|
||||
to ignore from the input.
|
||||
|
||||
If *canonical* is true, non-zero padding bits are rejected.
|
||||
See :func:`binascii.a2b_base32` for details.
|
||||
|
||||
A :exc:`binascii.Error` is raised if *s* is
|
||||
incorrectly padded or if there are non-alphabet characters present in the
|
||||
input.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Added the *ignorechars* and *padded* parameters.
|
||||
Added the *canonical*, *ignorechars*, and *padded* parameters.
|
||||
|
||||
|
||||
.. function:: b32hexencode(s, *, padded=True, wrapcol=0)
|
||||
|
|
@ -224,7 +230,7 @@ POST request.
|
|||
Added the *padded* and *wrapcol* parameters.
|
||||
|
||||
|
||||
.. function:: b32hexdecode(s, casefold=False, *, padded=True, ignorechars=b'')
|
||||
.. function:: b32hexdecode(s, casefold=False, *, padded=True, ignorechars=b'', canonical=False)
|
||||
|
||||
Similar to :func:`b32decode` but uses the Extended Hex Alphabet, as defined in
|
||||
:rfc:`4648`.
|
||||
|
|
@ -237,7 +243,7 @@ POST request.
|
|||
.. versionadded:: 3.10
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Added the *ignorechars* and *padded* parameters.
|
||||
Added the *canonical*, *ignorechars*, and *padded* parameters.
|
||||
|
||||
|
||||
.. function:: b16encode(s, *, wrapcol=0)
|
||||
|
|
@ -317,7 +323,7 @@ Refer to the documentation of the individual functions for more information.
|
|||
.. versionadded:: 3.4
|
||||
|
||||
|
||||
.. function:: a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v')
|
||||
.. function:: a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v', canonical=False)
|
||||
|
||||
Decode the Ascii85 encoded :term:`bytes-like object` or ASCII string *b* and
|
||||
return the decoded :class:`bytes`.
|
||||
|
|
@ -334,8 +340,16 @@ Refer to the documentation of the individual functions for more information.
|
|||
This should only contain whitespace characters, and by
|
||||
default contains all whitespace characters in ASCII.
|
||||
|
||||
If *canonical* is true, non-canonical encodings are rejected.
|
||||
See :func:`binascii.a2b_ascii85` for details.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
.. versionchanged:: next
|
||||
Added the *canonical* parameter.
|
||||
Single-character final groups are now always rejected as encoding
|
||||
violations.
|
||||
|
||||
|
||||
.. function:: b85encode(b, pad=False, *, wrapcol=0)
|
||||
|
||||
|
|
@ -355,7 +369,7 @@ Refer to the documentation of the individual functions for more information.
|
|||
Added the *wrapcol* parameter.
|
||||
|
||||
|
||||
.. function:: b85decode(b, *, ignorechars=b'')
|
||||
.. function:: b85decode(b, *, ignorechars=b'', canonical=False)
|
||||
|
||||
Decode the base85-encoded :term:`bytes-like object` or ASCII string *b* and
|
||||
return the decoded :class:`bytes`. Padding is implicitly removed, if
|
||||
|
|
@ -364,10 +378,15 @@ Refer to the documentation of the individual functions for more information.
|
|||
*ignorechars* should be a :term:`bytes-like object` containing characters
|
||||
to ignore from the input.
|
||||
|
||||
If *canonical* is true, non-canonical encodings are rejected.
|
||||
See :func:`binascii.a2b_base85` for details.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Added the *ignorechars* parameter.
|
||||
Added the *canonical* and *ignorechars* parameters.
|
||||
Single-character final groups are now always rejected as encoding
|
||||
violations.
|
||||
|
||||
|
||||
.. function:: z85encode(s, pad=False, *, wrapcol=0)
|
||||
|
|
@ -392,7 +411,7 @@ Refer to the documentation of the individual functions for more information.
|
|||
Added the *wrapcol* parameter.
|
||||
|
||||
|
||||
.. function:: z85decode(s, *, ignorechars=b'')
|
||||
.. function:: z85decode(s, *, ignorechars=b'', canonical=False)
|
||||
|
||||
Decode the Z85-encoded :term:`bytes-like object` or ASCII string *s* and
|
||||
return the decoded :class:`bytes`. See `Z85 specification
|
||||
|
|
@ -401,10 +420,15 @@ Refer to the documentation of the individual functions for more information.
|
|||
*ignorechars* should be a :term:`bytes-like object` containing characters
|
||||
to ignore from the input.
|
||||
|
||||
If *canonical* is true, non-canonical encodings are rejected.
|
||||
See :func:`binascii.a2b_base85` for details.
|
||||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Added the *ignorechars* parameter.
|
||||
Added the *canonical* and *ignorechars* parameters.
|
||||
Single-character final groups are now always rejected as encoding
|
||||
violations.
|
||||
|
||||
|
||||
.. _base64-legacy:
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ The :mod:`!binascii` module defines the following functions:
|
|||
Added the *backtick* parameter.
|
||||
|
||||
|
||||
.. function:: a2b_base64(string, /, *, padded=True, alphabet=BASE64_ALPHABET, strict_mode=False)
|
||||
a2b_base64(string, /, *, ignorechars, padded=True, alphabet=BASE64_ALPHABET, strict_mode=True)
|
||||
.. function:: a2b_base64(string, /, *, padded=True, alphabet=BASE64_ALPHABET, strict_mode=False, canonical=False)
|
||||
a2b_base64(string, /, *, ignorechars, padded=True, alphabet=BASE64_ALPHABET, strict_mode=True, canonical=False)
|
||||
|
||||
Convert a block of base64 data back to binary and return the binary data. More
|
||||
than one line may be passed at a time.
|
||||
|
|
@ -83,11 +83,15 @@ The :mod:`!binascii` module defines the following functions:
|
|||
* Contains no excess data after padding (including excess padding, newlines, etc.).
|
||||
* Does not start with a padding.
|
||||
|
||||
If *canonical* is true, non-zero padding bits in the last group are rejected
|
||||
with :exc:`binascii.Error`, enforcing canonical encoding as defined in
|
||||
:rfc:`4648` section 3.5. This check is independent of *strict_mode*.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Added the *strict_mode* parameter.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Added the *alphabet*, *ignorechars* and *padded* parameters.
|
||||
Added the *alphabet*, *canonical*, *ignorechars*, and *padded* parameters.
|
||||
|
||||
|
||||
.. function:: b2a_base64(data, *, padded=True, alphabet=BASE64_ALPHABET, wrapcol=0, newline=True)
|
||||
|
|
@ -113,7 +117,7 @@ The :mod:`!binascii` module defines the following functions:
|
|||
Added the *alphabet*, *padded* and *wrapcol* parameters.
|
||||
|
||||
|
||||
.. function:: a2b_ascii85(string, /, *, foldspaces=False, adobe=False, ignorechars=b'')
|
||||
.. function:: a2b_ascii85(string, /, *, foldspaces=False, adobe=False, ignorechars=b'', canonical=False)
|
||||
|
||||
Convert Ascii85 data back to binary and return the binary data.
|
||||
|
||||
|
|
@ -122,7 +126,8 @@ The :mod:`!binascii` module defines the following functions:
|
|||
characters). Each group encodes 32 bits of binary data in the range from
|
||||
``0`` to ``2 ** 32 - 1``, inclusive. The special character ``z`` is
|
||||
accepted as a short form of the group ``!!!!!``, which encodes four
|
||||
consecutive null bytes.
|
||||
consecutive null bytes. A single-character final group is always rejected
|
||||
as an encoding violation.
|
||||
|
||||
*foldspaces* is a flag that specifies whether the 'y' short sequence
|
||||
should be accepted as shorthand for 4 consecutive spaces (ASCII 0x20).
|
||||
|
|
@ -135,6 +140,12 @@ The :mod:`!binascii` module defines the following functions:
|
|||
to ignore from the input.
|
||||
This should only contain whitespace characters.
|
||||
|
||||
If *canonical* is true, non-canonical encodings are rejected with
|
||||
:exc:`binascii.Error`. Here "canonical" means the encoding that
|
||||
:func:`b2a_ascii85` would produce: the ``z`` abbreviation must be used
|
||||
for all-zero groups (rather than ``!!!!!``), and partial final groups
|
||||
must use the same padding digits as the encoder.
|
||||
|
||||
Invalid Ascii85 data will raise :exc:`binascii.Error`.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
|
@ -163,7 +174,7 @@ The :mod:`!binascii` module defines the following functions:
|
|||
.. versionadded:: 3.15
|
||||
|
||||
|
||||
.. function:: a2b_base85(string, /, *, alphabet=BASE85_ALPHABET, ignorechars=b'')
|
||||
.. function:: a2b_base85(string, /, *, alphabet=BASE85_ALPHABET, ignorechars=b'', canonical=False)
|
||||
|
||||
Convert Base85 data back to binary and return the binary data.
|
||||
More than one line may be passed at a time.
|
||||
|
|
@ -171,7 +182,8 @@ The :mod:`!binascii` module defines the following functions:
|
|||
Valid Base85 data contains characters from the Base85 alphabet in groups
|
||||
of five (except for the final group, which may have from two to five
|
||||
characters). Each group encodes 32 bits of binary data in the range from
|
||||
``0`` to ``2 ** 32 - 1``, inclusive.
|
||||
``0`` to ``2 ** 32 - 1``, inclusive. A single-character final group is
|
||||
always rejected as an encoding violation.
|
||||
|
||||
Optional *alphabet* must be a :class:`bytes` object of length 85 which
|
||||
specifies an alternative alphabet.
|
||||
|
|
@ -179,6 +191,11 @@ The :mod:`!binascii` module defines the following functions:
|
|||
*ignorechars* should be a :term:`bytes-like object` containing characters
|
||||
to ignore from the input.
|
||||
|
||||
If *canonical* is true, non-canonical encodings are rejected with
|
||||
:exc:`binascii.Error`. Here "canonical" means the encoding that
|
||||
:func:`b2a_base85` would produce: partial final groups must use the
|
||||
same padding digits as the encoder.
|
||||
|
||||
Invalid Base85 data will raise :exc:`binascii.Error`.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
|
@ -202,7 +219,7 @@ The :mod:`!binascii` module defines the following functions:
|
|||
.. versionadded:: 3.15
|
||||
|
||||
|
||||
.. function:: a2b_base32(string, /, *, padded=True, alphabet=BASE32_ALPHABET, ignorechars=b'')
|
||||
.. function:: a2b_base32(string, /, *, padded=True, alphabet=BASE32_ALPHABET, ignorechars=b'', canonical=False)
|
||||
|
||||
Convert base32 data back to binary and return the binary data.
|
||||
|
||||
|
|
@ -231,6 +248,10 @@ The :mod:`!binascii` module defines the following functions:
|
|||
presented before the end of the encoded data and the excess pad characters
|
||||
will be ignored.
|
||||
|
||||
If *canonical* is true, non-zero padding bits in the last group are rejected
|
||||
with :exc:`binascii.Error`, enforcing canonical encoding as defined in
|
||||
:rfc:`4648` section 3.5.
|
||||
|
||||
Invalid base32 data will raise :exc:`binascii.Error`.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
|
|||
|
||||
.. method:: setfirstweekday(firstweekday)
|
||||
|
||||
Set the first weekday to *firstweekday*, passed as an :class:`int` (0--6)
|
||||
Set the first weekday to *firstweekday*, passed as an :class:`int` (0--6).
|
||||
|
||||
Identical to setting the :attr:`~Calendar.firstweekday` property.
|
||||
|
||||
.. method:: iterweekdays()
|
||||
|
||||
Return an iterator for the week day numbers that will be used for one
|
||||
Return an iterator for the weekday numbers that will be used for one
|
||||
week. The first value from the iterator will be the same as the value of
|
||||
the :attr:`~Calendar.firstweekday` property.
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
|
|||
Return an iterator for the month *month* in the year *year* similar to
|
||||
:meth:`itermonthdates`, but not restricted by the :class:`datetime.date`
|
||||
range. Days returned will be tuples consisting of a day of the month
|
||||
number and a week day number.
|
||||
number and a weekday number.
|
||||
|
||||
|
||||
.. method:: itermonthdays3(year, month)
|
||||
|
|
@ -408,7 +408,7 @@ For simple text calendars this module provides the following functions.
|
|||
|
||||
.. function:: monthrange(year, month)
|
||||
|
||||
Returns weekday of first day of the month and number of days in month, for the
|
||||
Returns weekday of first day of the month and number of days in month, for the
|
||||
specified *year* and *month*.
|
||||
|
||||
|
||||
|
|
@ -446,7 +446,7 @@ For simple text calendars this module provides the following functions.
|
|||
An unrelated but handy function that takes a time tuple such as returned by
|
||||
the :func:`~time.gmtime` function in the :mod:`time` module, and returns the
|
||||
corresponding Unix timestamp value, assuming an epoch of 1970, and the POSIX
|
||||
encoding. In fact, :func:`time.gmtime` and :func:`timegm` are each others'
|
||||
encoding. In fact, :func:`time.gmtime` and :func:`timegm` are each other's
|
||||
inverse.
|
||||
|
||||
|
||||
|
|
@ -580,9 +580,14 @@ The :mod:`!calendar` module defines the following exceptions:
|
|||
|
||||
.. exception:: IllegalMonthError(month)
|
||||
|
||||
A subclass of :exc:`ValueError`,
|
||||
A subclass of :exc:`ValueError` and :exc:`IndexError`,
|
||||
raised when the given month number is outside of the range 1-12 (inclusive).
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
:exc:`IllegalMonthError` is now also a subclass of
|
||||
:exc:`ValueError`. New code should avoid catching
|
||||
:exc:`IndexError`.
|
||||
|
||||
.. attribute:: month
|
||||
|
||||
The invalid month number.
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ For example::
|
|||
.. versionadded:: 3.10
|
||||
|
||||
The usual dictionary methods are available for :class:`Counter` objects
|
||||
except for two which work differently for counters.
|
||||
except for these two which work differently for counters:
|
||||
|
||||
.. method:: fromkeys(iterable)
|
||||
|
||||
|
|
@ -1346,7 +1346,14 @@ attribute.
|
|||
A real dictionary used to store the contents of the :class:`UserDict`
|
||||
class.
|
||||
|
||||
:class:`!UserDict` instances also override the following method:
|
||||
|
||||
.. method:: popitem
|
||||
|
||||
Remove and return a ``(key, value)`` pair from the wrapped dictionary. Pairs are
|
||||
returned in the same order as ``data.popitem()``. (For the default
|
||||
:meth:`dict.popitem`, this order is :abbr:`LIFO (last-in, first-out)`.) If the
|
||||
dictionary is empty, raises a :exc:`KeyError`.
|
||||
|
||||
:class:`UserList` objects
|
||||
-------------------------
|
||||
|
|
|
|||
|
|
@ -1735,7 +1735,7 @@ If wrapping a shared library with :mod:`!ctypes`, consider determining the
|
|||
shared library name at development time, and hardcoding it into the wrapper
|
||||
module instead of using :func:`!find_library` to locate the library
|
||||
at runtime.
|
||||
Also consider addding a configuration option or environment variable to let
|
||||
Also consider adding a configuration option or environment variable to let
|
||||
users select a library to use, and then perhaps use :func:`!find_library`
|
||||
as a default or fallback.
|
||||
|
||||
|
|
@ -1756,11 +1756,10 @@ as a default or fallback.
|
|||
(or by) Python.
|
||||
It is recommended to only use this function as a default or fallback,
|
||||
|
||||
.. deprecated:: 3.15
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
This function is :term:`soft deprecated`.
|
||||
It is kept for use in cases where it works, but not expected to be
|
||||
updated for additional platforms and configurations.
|
||||
This function is kept for use in cases where it works, but not expected to
|
||||
be updated for additional platforms and configurations.
|
||||
|
||||
On Linux, :func:`!find_library` tries to run external
|
||||
programs (``/sbin/ldconfig``, ``gcc``, ``objdump`` and ``ld``) to find the
|
||||
|
|
@ -3191,8 +3190,8 @@ Arrays and pointers
|
|||
Equivalent to ``type * length``, where *type* is a
|
||||
:mod:`!ctypes` data type and *length* an integer.
|
||||
|
||||
This function is :term:`soft deprecated` in favor of multiplication.
|
||||
There are no plans to remove it.
|
||||
.. soft-deprecated:: 3.14
|
||||
In favor of multiplication.
|
||||
|
||||
|
||||
.. class:: _Pointer
|
||||
|
|
|
|||
|
|
@ -371,8 +371,8 @@ Module contents
|
|||
Converts the dataclass *obj* to a dict (by using the
|
||||
factory function *dict_factory*). Each dataclass is converted
|
||||
to a dict of its fields, as ``name: value`` pairs. dataclasses, dicts,
|
||||
lists, and tuples are recursed into. Other objects are copied with
|
||||
:func:`copy.deepcopy`.
|
||||
frozendicts, lists, and tuples are recursed into. Other objects are copied
|
||||
with :func:`copy.deepcopy`.
|
||||
|
||||
Example of using :func:`!asdict` on nested dataclasses::
|
||||
|
||||
|
|
@ -402,8 +402,8 @@ Module contents
|
|||
|
||||
Converts the dataclass *obj* to a tuple (by using the
|
||||
factory function *tuple_factory*). Each dataclass is converted
|
||||
to a tuple of its field values. dataclasses, dicts, lists, and
|
||||
tuples are recursed into. Other objects are copied with
|
||||
to a tuple of its field values. dataclasses, dicts, frozendicts, lists,
|
||||
and tuples are recursed into. Other objects are copied with
|
||||
:func:`copy.deepcopy`.
|
||||
|
||||
Continuing from the previous example::
|
||||
|
|
|
|||
|
|
@ -606,12 +606,11 @@ Other constructors, all class methods:
|
|||
|
||||
.. note::
|
||||
|
||||
If *format* specifies a day of month without a year a
|
||||
:exc:`DeprecationWarning` is emitted. This is to avoid a quadrennial
|
||||
If *format* specifies a day of month (``%d``) without a year,
|
||||
:exc:`ValueError` is raised. This is to avoid a quadrennial
|
||||
leap year bug in code seeking to parse only a month and day as the
|
||||
default year used in absence of one in the format is not a leap year.
|
||||
Such *format* values may raise an error as of Python 3.15. The
|
||||
workaround is to always include a year in your *format*. If parsing
|
||||
The workaround is to always include a year in your *format*. If parsing
|
||||
*date_string* values that do not have a year, explicitly add a year that
|
||||
is a leap year before parsing:
|
||||
|
||||
|
|
@ -1180,14 +1179,13 @@ Other constructors, all class methods:
|
|||
time tuple. See also :ref:`strftime-strptime-behavior` and
|
||||
:meth:`datetime.fromisoformat`.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
.. versionchanged:: 3.15
|
||||
|
||||
If *format* specifies a day of month without a year a
|
||||
:exc:`DeprecationWarning` is now emitted. This is to avoid a quadrennial
|
||||
If *format* specifies a day of month (``%d``) without a year,
|
||||
:exc:`ValueError` is raised. This is to avoid a quadrennial
|
||||
leap year bug in code seeking to parse only a month and day as the
|
||||
default year used in absence of one in the format is not a leap year.
|
||||
Such *format* values may raise an error as of Python 3.15. The
|
||||
workaround is to always include a year in your *format*. If parsing
|
||||
The workaround is to always include a year in your *format*. If parsing
|
||||
*date_string* values that do not have a year, explicitly add a year that
|
||||
is a leap year before parsing:
|
||||
|
||||
|
|
@ -2572,13 +2570,13 @@ requires, and these work on all supported platforms.
|
|||
| | truncated to an integer as a | | |
|
||||
| | zero-padded decimal number. | | |
|
||||
+-----------+--------------------------------+------------------------+-------+
|
||||
| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) |
|
||||
| | zero-padded decimal number. | | |
|
||||
| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9), |
|
||||
| | zero-padded decimal number. | | \(10) |
|
||||
+-----------+--------------------------------+------------------------+-------+
|
||||
| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/28/25 | \(9) |
|
||||
| | | | |
|
||||
+-----------+--------------------------------+------------------------+-------+
|
||||
| ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | |
|
||||
| ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | \(10) |
|
||||
| | space-padded decimal number. | | |
|
||||
+-----------+--------------------------------+------------------------+-------+
|
||||
| ``%F`` | Equivalent to ``%Y-%m-%d``, | 2025-10-11, | |
|
||||
|
|
@ -2919,11 +2917,12 @@ Notes:
|
|||
>>> dt.datetime.strptime(f"{month_day};1984", "%m/%d;%Y") # No leap year bug.
|
||||
datetime.datetime(1984, 2, 29, 0, 0)
|
||||
|
||||
.. deprecated-removed:: 3.13 3.15
|
||||
.. versionchanged:: 3.15
|
||||
Using ``%d`` without a year now raises :exc:`ValueError`.
|
||||
|
||||
.. deprecated-removed:: 3.15 3.17
|
||||
:meth:`~.datetime.strptime` calls using a format string containing
|
||||
a day of month without a year now emit a
|
||||
:exc:`DeprecationWarning`. In 3.15 or later we may change this into
|
||||
an error or change the default year to a leap year. See :gh:`70647`.
|
||||
``%e`` without a year now emit a :exc:`DeprecationWarning`.
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ operation is being performed, so the intermediate analysis object isn't useful:
|
|||
|
||||
.. versionchanged:: 3.10
|
||||
The :pep:`626` :meth:`~codeobject.co_lines` method is used instead of the
|
||||
:attr:`~codeobject.co_firstlineno` and :attr:`~codeobject.co_lnotab`
|
||||
:attr:`~codeobject.co_firstlineno` and :attr:`!codeobject.co_lnotab`
|
||||
attributes of the :ref:`code object <code-objects>`.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ Data types
|
|||
|
||||
.. method:: EnumType.__len__(cls)
|
||||
|
||||
Returns the number of member in *cls*::
|
||||
Returns the number of members in *cls*::
|
||||
|
||||
>>> len(Color)
|
||||
3
|
||||
|
|
@ -502,7 +502,7 @@ Data types
|
|||
Using :class:`auto` with :class:`Enum` results in integers of increasing value,
|
||||
starting with ``1``.
|
||||
|
||||
.. versionchanged:: 3.12 Added :ref:`enum-dataclass-support`
|
||||
.. versionchanged:: 3.12 Added :ref:`enum-dataclass-support`.
|
||||
|
||||
.. method:: Enum._add_alias_
|
||||
|
||||
|
|
@ -977,9 +977,9 @@ Utilities and decorators
|
|||
|
||||
*auto* can be used in place of a value. If used, the *Enum* machinery will
|
||||
call an :class:`Enum`'s :meth:`~Enum._generate_next_value_` to get an appropriate value.
|
||||
For :class:`Enum` and :class:`IntEnum` that appropriate value will be the last value plus
|
||||
one; for :class:`Flag` and :class:`IntFlag` it will be the first power-of-two greater
|
||||
than the highest value; for :class:`StrEnum` it will be the lower-cased version of
|
||||
For :class:`Enum` and :class:`IntEnum` that appropriate value will be the highest value seen
|
||||
plus one; for :class:`Flag` and :class:`IntFlag` it will be the first power-of-two greater
|
||||
than the highest value seen; for :class:`StrEnum` it will be the lower-cased version of
|
||||
the member's name. Care must be taken if mixing *auto()* with manually
|
||||
specified values.
|
||||
|
||||
|
|
@ -989,8 +989,8 @@ Utilities and decorators
|
|||
* ``FIRST = auto()`` will work (auto() is replaced with ``1``);
|
||||
* ``SECOND = auto(), -2`` will work (auto is replaced with ``2``, so ``2, -2`` is
|
||||
used to create the ``SECOND`` enum member;
|
||||
* ``THREE = [auto(), -3]`` will *not* work (``[<auto instance>, -3]`` is used to
|
||||
create the ``THREE`` enum member)
|
||||
* ``THIRD = [auto(), -3]`` will *not* work (``[<auto instance>, -3]`` is used to
|
||||
create the ``THIRD`` enum member)
|
||||
|
||||
.. versionchanged:: 3.11.1
|
||||
|
||||
|
|
@ -1000,7 +1000,7 @@ Utilities and decorators
|
|||
``_generate_next_value_`` can be overridden to customize the values used by
|
||||
*auto*.
|
||||
|
||||
.. note:: in 3.13 the default ``_generate_next_value_`` will always return
|
||||
.. note:: In version 3.13 the default ``_generate_next_value_`` will always return
|
||||
the highest member value incremented by 1, and will fail if any
|
||||
member is an incompatible type.
|
||||
|
||||
|
|
@ -1010,7 +1010,7 @@ Utilities and decorators
|
|||
enumerations. It allows member attributes to have the same names as members
|
||||
themselves.
|
||||
|
||||
.. note:: the *property* and the member must be defined in separate classes;
|
||||
.. note:: The *property* and the member must be defined in separate classes;
|
||||
for example, the *value* and *name* attributes are defined in the
|
||||
*Enum* class, and *Enum* subclasses can define members with the
|
||||
names ``value`` and ``name``.
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ functions: :func:`fnmatch`, :func:`fnmatchcase`, :func:`.filter`, :func:`.filter
|
|||
.. function:: translate(pat)
|
||||
|
||||
Return the shell-style pattern *pat* converted to a regular expression for
|
||||
using with :func:`re.match`. The pattern is expected to be a :class:`str`.
|
||||
using with :func:`re.prefixmatch`. The pattern is expected to be a
|
||||
:class:`str`.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
@ -113,7 +114,7 @@ functions: :func:`fnmatch`, :func:`fnmatchcase`, :func:`.filter`, :func:`.filter
|
|||
>>> regex
|
||||
'(?s:.*\\.txt)\\z'
|
||||
>>> reobj = re.compile(regex)
|
||||
>>> reobj.match('foobar.txt')
|
||||
>>> reobj.prefixmatch('foobar.txt')
|
||||
<re.Match object; span=(0, 10), match='foobar.txt'>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ are always available. They are listed here in alphabetical order.
|
|||
If the given source is a string, then leading and trailing spaces and tabs
|
||||
are stripped.
|
||||
|
||||
See :func:`ast.literal_eval` for a function that can safely evaluate strings
|
||||
See :func:`ast.literal_eval` for a function to evaluate strings
|
||||
with expressions containing only literals.
|
||||
|
||||
.. audit-event:: exec code_object eval
|
||||
|
|
|
|||
|
|
@ -140,7 +140,8 @@ The :mod:`!glob` module defines the following functions:
|
|||
.. function:: translate(pathname, *, recursive=False, include_hidden=False, seps=None)
|
||||
|
||||
Convert the given path specification to a regular expression for use with
|
||||
:func:`re.match`. The path specification can contain shell-style wildcards.
|
||||
:func:`re.prefixmatch`. The path specification can contain shell-style
|
||||
wildcards.
|
||||
|
||||
For example:
|
||||
|
||||
|
|
@ -150,7 +151,7 @@ The :mod:`!glob` module defines the following functions:
|
|||
>>> regex
|
||||
'(?s:(?:.+/)?[^/]*\\.txt)\\z'
|
||||
>>> reobj = re.compile(regex)
|
||||
>>> reobj.match('foo/bar/baz.txt')
|
||||
>>> reobj.prefixmatch('foo/bar/baz.txt')
|
||||
<re.Match object; span=(0, 15), match='foo/bar/baz.txt'>
|
||||
|
||||
Path separators and segments are meaningful to this function, unlike
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ instantiation, of which this module provides three different variants:
|
|||
|
||||
This class is used to handle the HTTP requests that arrive at the server. By
|
||||
itself, it cannot respond to any actual HTTP requests; it must be subclassed
|
||||
to handle each request method (e.g. GET or POST).
|
||||
to handle each request method (for example, ``'GET'`` or ``'POST'``).
|
||||
:class:`BaseHTTPRequestHandler` provides a number of class and instance
|
||||
variables, and methods for use by subclasses.
|
||||
|
||||
|
|
@ -241,7 +241,7 @@ instantiation, of which this module provides three different variants:
|
|||
request header it responds back with a ``100 Continue`` followed by ``200
|
||||
OK`` headers.
|
||||
This method can be overridden to raise an error if the server does not
|
||||
want the client to continue. For e.g. server can choose to send ``417
|
||||
want the client to continue. For example, the server can choose to send ``417
|
||||
Expectation Failed`` as a response header and ``return False``.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
|
@ -469,7 +469,9 @@ Command-line interface
|
|||
|
||||
:mod:`!http.server` can also be invoked directly using the :option:`-m`
|
||||
switch of the interpreter. The following example illustrates how to serve
|
||||
files relative to the current directory::
|
||||
files relative to the current directory:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m http.server [OPTIONS] [port]
|
||||
|
||||
|
|
@ -480,7 +482,9 @@ The following options are accepted:
|
|||
.. option:: port
|
||||
|
||||
The server listens to port 8000 by default. The default can be overridden
|
||||
by passing the desired port number as an argument::
|
||||
by passing the desired port number as an argument:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m http.server 9000
|
||||
|
||||
|
|
@ -489,7 +493,9 @@ The following options are accepted:
|
|||
Specifies a specific address to which it should bind. Both IPv4 and IPv6
|
||||
addresses are supported. By default, the server binds itself to all
|
||||
interfaces. For example, the following command causes the server to bind
|
||||
to localhost only::
|
||||
to localhost only:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m http.server --bind 127.0.0.1
|
||||
|
||||
|
|
@ -502,7 +508,9 @@ The following options are accepted:
|
|||
|
||||
Specifies a directory to which it should serve the files. By default,
|
||||
the server uses the current directory. For example, the following command
|
||||
uses a specific directory::
|
||||
uses a specific directory:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m http.server --directory /tmp/
|
||||
|
||||
|
|
@ -512,7 +520,9 @@ The following options are accepted:
|
|||
|
||||
Specifies the HTTP version to which the server is conformant. By default,
|
||||
the server is conformant to HTTP/1.0. For example, the following command
|
||||
runs an HTTP/1.1 conformant server::
|
||||
runs an HTTP/1.1 conformant server:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m http.server --protocol HTTP/1.1
|
||||
|
||||
|
|
@ -520,7 +530,9 @@ The following options are accepted:
|
|||
|
||||
.. option:: --tls-cert
|
||||
|
||||
Specifies a TLS certificate chain for HTTPS connections::
|
||||
Specifies a TLS certificate chain for HTTPS connections:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m http.server --tls-cert fullchain.pem
|
||||
|
||||
|
|
@ -536,14 +548,16 @@ The following options are accepted:
|
|||
|
||||
.. option:: --tls-password-file
|
||||
|
||||
Specifies the password file for password-protected private keys::
|
||||
Specifies the password file for password-protected private keys:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m http.server \
|
||||
--tls-cert cert.pem \
|
||||
--tls-key key.pem \
|
||||
--tls-password-file password.txt
|
||||
|
||||
This option requires `--tls-cert`` to be specified.
|
||||
This option requires ``--tls-cert`` to be specified.
|
||||
|
||||
.. versionadded:: 3.14
|
||||
|
||||
|
|
@ -561,7 +575,7 @@ to be served.
|
|||
|
||||
Methods :meth:`BaseHTTPRequestHandler.send_header` and
|
||||
:meth:`BaseHTTPRequestHandler.send_response_only` assume sanitized input
|
||||
and does not perform input validation such as checking for the presence of CRLF
|
||||
and do not perform input validation such as checking for the presence of CRLF
|
||||
sequences. Untrusted input may result in HTTP Header injection attacks.
|
||||
|
||||
Earlier versions of Python did not scrub control characters from the
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ ABC hierarchy::
|
|||
This method can potentially yield a very large number of objects, and
|
||||
it may carry out IO operations when computing these values.
|
||||
|
||||
Because of this, it will generaly be desirable to compute the result
|
||||
Because of this, it will generally be desirable to compute the result
|
||||
values on-the-fly, as they are needed. As such, the returned object is
|
||||
only guaranteed to be an :class:`iterable <collections.abc.Iterable>`,
|
||||
instead of a :class:`list` or other
|
||||
|
|
@ -340,7 +340,7 @@ ABC hierarchy::
|
|||
This method can potentially yield a very large number of objects, and
|
||||
it may carry out IO operations when computing these values.
|
||||
|
||||
Because of this, it will generaly be desirable to compute the result
|
||||
Because of this, it will generally be desirable to compute the result
|
||||
values on-the-fly, as they are needed. As such, the returned object is
|
||||
only guaranteed to be an :class:`iterable <collections.abc.Iterable>`,
|
||||
instead of a :class:`list` or other
|
||||
|
|
|
|||
|
|
@ -195,10 +195,6 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
|
|||
| | | read more :ref:`here |
|
||||
| | | <inspect-module-co-flags>`|
|
||||
+-----------------+-------------------+---------------------------+
|
||||
| | co_lnotab | encoded mapping of line |
|
||||
| | | numbers to bytecode |
|
||||
| | | indices |
|
||||
+-----------------+-------------------+---------------------------+
|
||||
| | co_freevars | tuple of names of free |
|
||||
| | | variables (referenced via |
|
||||
| | | a function's closure) |
|
||||
|
|
|
|||
|
|
@ -833,6 +833,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
|
|||
from collections import Counter, deque
|
||||
from contextlib import suppress
|
||||
from functools import reduce
|
||||
from heapq import heappush, heappushpop, heappush_max, heappushpop_max
|
||||
from math import comb, isqrt, prod, sumprod
|
||||
from operator import getitem, is_not, itemgetter, mul, neg, truediv
|
||||
|
||||
|
|
@ -848,11 +849,6 @@ and :term:`generators <generator>` which incur interpreter overhead.
|
|||
# prepend(1, [2, 3, 4]) → 1 2 3 4
|
||||
return chain([value], iterable)
|
||||
|
||||
def running_mean(iterable):
|
||||
"Yield the average of all values seen so far."
|
||||
# running_mean([8.5, 9.5, 7.5, 6.5]) → 8.5 9.0 8.5 8.0
|
||||
return map(truediv, accumulate(iterable), count(1))
|
||||
|
||||
def repeatfunc(function, times=None, *args):
|
||||
"Repeat calls to a function with specified arguments."
|
||||
if times is None:
|
||||
|
|
@ -1150,6 +1146,49 @@ and :term:`generators <generator>` which incur interpreter overhead.
|
|||
return n
|
||||
|
||||
|
||||
# ==== Running statistics ====
|
||||
|
||||
def running_mean(iterable):
|
||||
"Average of values seen so far."
|
||||
# running_mean([37, 33, 38, 28]) → 37 35 36 34
|
||||
return map(truediv, accumulate(iterable), count(1))
|
||||
|
||||
def running_min(iterable):
|
||||
"Smallest of values seen so far."
|
||||
# running_min([37, 33, 38, 28]) → 37 33 33 28
|
||||
return accumulate(iterable, func=min)
|
||||
|
||||
def running_max(iterable):
|
||||
"Largest of values seen so far."
|
||||
# running_max([37, 33, 38, 28]) → 37 37 38 38
|
||||
return accumulate(iterable, func=max)
|
||||
|
||||
def running_median(iterable):
|
||||
"Median of values seen so far."
|
||||
# running_median([37, 33, 38, 28]) → 37 35 37 35
|
||||
read = iter(iterable).__next__
|
||||
lo = [] # max-heap
|
||||
hi = [] # min-heap the same size as or one smaller than lo
|
||||
with suppress(StopIteration):
|
||||
while True:
|
||||
heappush_max(lo, heappushpop(hi, read()))
|
||||
yield lo[0]
|
||||
heappush(hi, heappushpop_max(lo, read()))
|
||||
yield (lo[0] + hi[0]) / 2
|
||||
|
||||
def running_statistics(iterable):
|
||||
"Aggregate statistics for values seen so far."
|
||||
# Generate tuples: (size, minimum, median, maximum, mean)
|
||||
t0, t1, t2, t3 = tee(iterable, 4)
|
||||
return zip(
|
||||
count(1),
|
||||
running_min(t0),
|
||||
running_median(t1),
|
||||
running_max(t2),
|
||||
running_mean(t3),
|
||||
)
|
||||
|
||||
|
||||
.. doctest::
|
||||
:hide:
|
||||
|
||||
|
|
@ -1226,10 +1265,6 @@ and :term:`generators <generator>` which incur interpreter overhead.
|
|||
[(0, 'a'), (1, 'b'), (2, 'c')]
|
||||
|
||||
|
||||
>>> list(running_mean([8.5, 9.5, 7.5, 6.5]))
|
||||
[8.5, 9.0, 8.5, 8.0]
|
||||
|
||||
|
||||
>>> for _ in loops(5):
|
||||
... print('hi')
|
||||
...
|
||||
|
|
@ -1789,6 +1824,28 @@ and :term:`generators <generator>` which incur interpreter overhead.
|
|||
True
|
||||
|
||||
|
||||
>>> list(running_mean([8.5, 9.5, 7.5, 6.5]))
|
||||
[8.5, 9.0, 8.5, 8.0]
|
||||
>>> list(running_mean([37, 33, 38, 28]))
|
||||
[37.0, 35.0, 36.0, 34.0]
|
||||
|
||||
|
||||
>>> list(running_min([37, 33, 38, 28]))
|
||||
[37, 33, 33, 28]
|
||||
|
||||
|
||||
>>> list(running_max([37, 33, 38, 28]))
|
||||
[37, 37, 38, 38]
|
||||
|
||||
|
||||
>>> list(running_median([37, 33, 38, 28]))
|
||||
[37, 35.0, 37, 35.0]
|
||||
|
||||
|
||||
>>> list(running_statistics([37, 33, 38, 28]))
|
||||
[(1, 37, 37, 37, 37.0), (2, 33, 35.0, 37, 35.0), (3, 33, 37, 38, 36.0), (4, 28, 35.0, 38, 34.0)]
|
||||
|
||||
|
||||
.. testcode::
|
||||
:hide:
|
||||
|
||||
|
|
|
|||
|
|
@ -781,9 +781,8 @@ the following functions from the :mod:`math.integer` module:
|
|||
Floats with integral values (like ``5.0``) are no longer accepted in the
|
||||
:func:`factorial` function.
|
||||
|
||||
.. deprecated:: 3.15
|
||||
These aliases are :term:`soft deprecated` in favor of the
|
||||
:mod:`math.integer` functions.
|
||||
.. soft-deprecated:: 3.15
|
||||
Use the :mod:`math.integer` functions instead of these aliases.
|
||||
|
||||
|
||||
Constants
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ the information :func:`init` sets up.
|
|||
.. versionchanged:: 3.8
|
||||
Added support for *url* being a :term:`path-like object`.
|
||||
|
||||
.. deprecated:: 3.13
|
||||
Passing a file path instead of URL is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.13
|
||||
Passing a file path instead of URL.
|
||||
Use :func:`guess_file_type` for this.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -932,7 +932,8 @@ For an example of the usage of queues for interprocess communication see
|
|||
standard library's :mod:`queue` module are raised to signal timeouts.
|
||||
|
||||
:class:`Queue` implements all the methods of :class:`queue.Queue` except for
|
||||
:meth:`~queue.Queue.task_done` and :meth:`~queue.Queue.join`.
|
||||
:meth:`~queue.Queue.task_done`, :meth:`~queue.Queue.join`, and
|
||||
:meth:`~queue.Queue.shutdown`.
|
||||
|
||||
.. method:: qsize()
|
||||
|
||||
|
|
@ -1335,12 +1336,12 @@ Connection objects are usually created using
|
|||
Note that multiple connection objects may be polled at once by
|
||||
using :func:`multiprocessing.connection.wait`.
|
||||
|
||||
.. method:: send_bytes(buffer[, offset[, size]])
|
||||
.. method:: send_bytes(buf[, offset[, size]])
|
||||
|
||||
Send byte data from a :term:`bytes-like object` as a complete message.
|
||||
|
||||
If *offset* is given then data is read from that position in *buffer*. If
|
||||
*size* is given then that many bytes will be read from buffer. Very large
|
||||
If *offset* is given then data is read from that position in *buf*. If
|
||||
*size* is given then that many bytes will be read from *buf*. Very large
|
||||
buffers (approximately 32 MiB+, though it depends on the OS) may raise a
|
||||
:exc:`ValueError` exception
|
||||
|
||||
|
|
@ -1360,18 +1361,18 @@ Connection objects are usually created using
|
|||
alias of :exc:`OSError`.
|
||||
|
||||
|
||||
.. method:: recv_bytes_into(buffer[, offset])
|
||||
.. method:: recv_bytes_into(buf[, offset])
|
||||
|
||||
Read into *buffer* a complete message of byte data sent from the other end
|
||||
Read into *buf* a complete message of byte data sent from the other end
|
||||
of the connection and return the number of bytes in the message. Blocks
|
||||
until there is something to receive. Raises
|
||||
:exc:`EOFError` if there is nothing left to receive and the other end was
|
||||
closed.
|
||||
|
||||
*buffer* must be a writable :term:`bytes-like object`. If
|
||||
*buf* must be a writable :term:`bytes-like object`. If
|
||||
*offset* is given then the message will be written into the buffer from
|
||||
that position. Offset must be a non-negative integer less than the
|
||||
length of *buffer* (in bytes).
|
||||
length of *buf* (in bytes).
|
||||
|
||||
If the buffer is too short then a :exc:`BufferTooShort` exception is
|
||||
raised and the complete message is available as ``e.args[0]`` where ``e``
|
||||
|
|
|
|||
|
|
@ -5110,9 +5110,8 @@ written in Python, such as a mail server's external command delivery program.
|
|||
Use :class:`subprocess.Popen` or :func:`subprocess.run` to
|
||||
control options like encodings.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The function is :term:`soft deprecated` and should no longer be used to
|
||||
write new code. The :mod:`subprocess` module is recommended instead.
|
||||
.. soft-deprecated:: 3.14
|
||||
The :mod:`subprocess` module is recommended instead.
|
||||
|
||||
|
||||
.. function:: posix_spawn(path, argv, env, *, file_actions=None, \
|
||||
|
|
@ -5340,9 +5339,8 @@ written in Python, such as a mail server's external command delivery program.
|
|||
.. versionchanged:: 3.6
|
||||
Accepts a :term:`path-like object`.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
These functions are :term:`soft deprecated` and should no longer be used
|
||||
to write new code. The :mod:`subprocess` module is recommended instead.
|
||||
.. soft-deprecated:: 3.14
|
||||
The :mod:`subprocess` module is recommended instead.
|
||||
|
||||
|
||||
.. data:: P_NOWAIT
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
--------------
|
||||
|
||||
.. image:: tachyon-logo.png
|
||||
.. image:: ../../Lib/profiling/sampling/_assets/tachyon-logo.png
|
||||
:alt: Tachyon logo
|
||||
:align: center
|
||||
:width: 300px
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ fine-tuning parameters.
|
|||
|
||||
.. _re-syntax:
|
||||
|
||||
Regular Expression Syntax
|
||||
Regular expression syntax
|
||||
-------------------------
|
||||
|
||||
A regular expression (or RE) specifies a set of strings that matches it; the
|
||||
|
|
@ -205,7 +205,7 @@ The special characters are:
|
|||
*without* establishing any backtracking points.
|
||||
This is the possessive version of the quantifier above.
|
||||
For example, on the 6-character string ``'aaaaaa'``, ``a{3,5}+aa``
|
||||
attempt to match 5 ``'a'`` characters, then, requiring 2 more ``'a'``\ s,
|
||||
attempts to match 5 ``'a'`` characters, then, requiring 2 more ``'a'``\ s,
|
||||
will need more characters than available and thus fail, while
|
||||
``a{3,5}aa`` will match with ``a{3,5}`` capturing 5, then 4 ``'a'``\ s
|
||||
by backtracking and then the final 2 ``'a'``\ s are matched by the final
|
||||
|
|
@ -717,7 +717,7 @@ three digits in length.
|
|||
|
||||
.. _contents-of-module-re:
|
||||
|
||||
Module Contents
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
The module defines several functions, constants, and an exception. Some of the
|
||||
|
|
@ -833,8 +833,8 @@ Flags
|
|||
will be conditionally ORed with other flags. Example of use as a default
|
||||
value::
|
||||
|
||||
def myfunc(text, flag=re.NOFLAG):
|
||||
return re.search(text, flag)
|
||||
def myfunc(pattern, text, flag=re.NOFLAG):
|
||||
return re.search(pattern, text, flag)
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
|
@ -931,7 +931,6 @@ Functions
|
|||
|
||||
|
||||
.. function:: prefixmatch(pattern, string, flags=0)
|
||||
.. function:: match(pattern, string, flags=0)
|
||||
|
||||
If zero or more characters at the beginning of *string* match the regular
|
||||
expression *pattern*, return a corresponding :class:`~re.Match`. Return
|
||||
|
|
@ -954,9 +953,14 @@ Functions
|
|||
:func:`~re.match`. Use that name when you need to retain compatibility with
|
||||
older Python versions.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
The alternate :func:`~re.prefixmatch` name of this API was added as a
|
||||
more explicitly descriptive name than :func:`~re.match`. Use it to better
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. function:: match(pattern, string, flags=0)
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
:func:`~re.match` has been :term:`soft deprecated` in favor of
|
||||
the alternate :func:`~re.prefixmatch` name of this API which is
|
||||
more explicitly descriptive. Use it to better
|
||||
express intent. The norm in other languages and regular expression
|
||||
implementations is to use the term *match* to refer to the behavior of
|
||||
what Python has always called :func:`~re.search`.
|
||||
|
|
@ -1246,7 +1250,7 @@ Exceptions
|
|||
|
||||
.. _re-objects:
|
||||
|
||||
Regular Expression Objects
|
||||
Regular expression objects
|
||||
--------------------------
|
||||
|
||||
.. class:: Pattern
|
||||
|
|
@ -1284,7 +1288,6 @@ Regular Expression Objects
|
|||
|
||||
|
||||
.. method:: Pattern.prefixmatch(string[, pos[, endpos]])
|
||||
.. method:: Pattern.match(string[, pos[, endpos]])
|
||||
|
||||
If zero or more characters at the *beginning* of *string* match this regular
|
||||
expression, return a corresponding :class:`~re.Match`. Return ``None`` if the
|
||||
|
|
@ -1309,9 +1312,14 @@ Regular Expression Objects
|
|||
:meth:`~Pattern.match`. Use that name when you need to retain compatibility
|
||||
with older Python versions.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
The alternate :meth:`~Pattern.prefixmatch` name of this API was added as
|
||||
a more explicitly descriptive name than :meth:`~Pattern.match`. Use it to
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. method:: Pattern.match(string[, pos[, endpos]])
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
:meth:`~Pattern.match` has been :term:`soft deprecated` in favor of
|
||||
the alternate :meth:`~Pattern.prefixmatch` name of this API which is
|
||||
more explicitly descriptive. Use it to
|
||||
better express intent. The norm in other languages and regular expression
|
||||
implementations is to use the term *match* to refer to the behavior of
|
||||
what Python has always called :meth:`~Pattern.search`.
|
||||
|
|
@ -1396,7 +1404,7 @@ Regular Expression Objects
|
|||
|
||||
.. _match-objects:
|
||||
|
||||
Match Objects
|
||||
Match objects
|
||||
-------------
|
||||
|
||||
Match objects always have a boolean value of ``True``.
|
||||
|
|
@ -1615,11 +1623,11 @@ when there is no match, you can test whether there was a match with a simple
|
|||
|
||||
.. _re-examples:
|
||||
|
||||
Regular Expression Examples
|
||||
Regular expression examples
|
||||
---------------------------
|
||||
|
||||
|
||||
Checking for a Pair
|
||||
Checking for a pair
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In this example, we'll use the following helper function to display match
|
||||
|
|
@ -1705,15 +1713,21 @@ expressions.
|
|||
| ``%x``, ``%X`` | ``[-+]?(0[xX])?[\dA-Fa-f]+`` |
|
||||
+--------------------------------+---------------------------------------------+
|
||||
|
||||
To extract the filename and numbers from a string like ::
|
||||
To extract the filename and numbers from a string like:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
/usr/sbin/sendmail - 0 errors, 4 warnings
|
||||
|
||||
you would use a :c:func:`!scanf` format like ::
|
||||
you would use a :c:func:`!scanf` format like:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
%s - %d errors, %d warnings
|
||||
|
||||
The equivalent regular expression would be ::
|
||||
The equivalent regular expression would be:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
(\S+) - (\d+) errors, (\d+) warnings
|
||||
|
||||
|
|
@ -1772,18 +1786,24 @@ not familiar with the Python API's divergence from what otherwise become the
|
|||
industry norm.
|
||||
|
||||
Quoting from the Zen Of Python (``python3 -m this``): *"Explicit is better than
|
||||
implicit"*. Anyone reading the name :func:`~re.prefixmatch` is likely to
|
||||
understand the intended semantics. When reading :func:`~re.match` there remains
|
||||
implicit"*. Anyone reading the name :func:`!prefixmatch` is likely to
|
||||
understand the intended semantics. When reading :func:`!match` there remains
|
||||
a seed of doubt about the intended behavior to anyone not already familiar with
|
||||
this old Python gotcha.
|
||||
|
||||
We **do not** plan to deprecate and remove the older *match* name,
|
||||
We **do not** plan to remove the older :func:`!match` name,
|
||||
as it has been used in code for over 30 years.
|
||||
Code supporting older versions of Python should continue to use *match*.
|
||||
It has been :term:`soft deprecated`:
|
||||
code supporting older versions of Python should continue to use :func:`!match`,
|
||||
while new code should prefer :func:`!prefixmatch`.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
:func:`!prefixmatch`
|
||||
|
||||
Making a Phonebook
|
||||
.. soft-deprecated:: 3.15
|
||||
:func:`!match`
|
||||
|
||||
Making a phonebook
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:func:`split` splits a string into a list delimited by the passed pattern. The
|
||||
|
|
@ -1844,7 +1864,7 @@ house number from the street name:
|
|||
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]
|
||||
|
||||
|
||||
Text Munging
|
||||
Text munging
|
||||
^^^^^^^^^^^^
|
||||
|
||||
:func:`sub` replaces every occurrence of a pattern with a string or the
|
||||
|
|
@ -1864,7 +1884,7 @@ in each word of a sentence except for the first and last characters::
|
|||
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'
|
||||
|
||||
|
||||
Finding all Adverbs
|
||||
Finding all adverbs
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:func:`findall` matches *all* occurrences of a pattern, not just the first
|
||||
|
|
@ -1877,7 +1897,7 @@ the following manner::
|
|||
['carefully', 'quickly']
|
||||
|
||||
|
||||
Finding all Adverbs and their Positions
|
||||
Finding all adverbs and their positions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If one wants more information about all matches of a pattern than the matched
|
||||
|
|
@ -1893,7 +1913,7 @@ to find all of the adverbs *and their positions* in some text, they would use
|
|||
40-47: quickly
|
||||
|
||||
|
||||
Raw String Notation
|
||||
Raw string notation
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Raw string notation (``r"text"``) keeps regular expressions sane. Without it,
|
||||
|
|
@ -1917,7 +1937,7 @@ functionally identical::
|
|||
<re.Match object; span=(0, 1), match='\\'>
|
||||
|
||||
|
||||
Writing a Tokenizer
|
||||
Writing a tokenizer
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A `tokenizer or scanner <https://en.wikipedia.org/wiki/Lexical_analysis>`_
|
||||
|
|
@ -1933,7 +1953,7 @@ successive matches::
|
|||
|
||||
class Token(NamedTuple):
|
||||
type: str
|
||||
value: str
|
||||
value: int | float | str
|
||||
line: int
|
||||
column: int
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ This document includes four main sections:
|
|||
PEP written by Marc-André Lemburg.
|
||||
|
||||
|
||||
.. We use the following practises for SQL code:
|
||||
.. We use the following practices for SQL code:
|
||||
- UPPERCASE for keywords
|
||||
- snake_case for schema
|
||||
- single quotes for string literals
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
.. note::
|
||||
|
||||
:mod:`!sys.monitoring` is a namespace within the :mod:`sys` module,
|
||||
not an independent module, so there is no need to
|
||||
``import sys.monitoring``, simply ``import sys`` and then use
|
||||
``sys.monitoring``.
|
||||
not an independent module, and ``import sys.monitoring`` would fail
|
||||
with a :exc:`ModuleNotFoundError`. Instead, simply ``import sys``
|
||||
and then use ``sys.monitoring``.
|
||||
|
||||
|
||||
This namespace provides access to the functions and constants necessary to
|
||||
|
|
@ -180,8 +180,8 @@ Local events
|
|||
''''''''''''
|
||||
|
||||
Local events are associated with normal execution of the program and happen
|
||||
at clearly defined locations. All local events can be disabled.
|
||||
The local events are:
|
||||
at clearly defined locations. All local events can be disabled
|
||||
per location. The local events are:
|
||||
|
||||
* :monitoring-event:`PY_START`
|
||||
* :monitoring-event:`PY_RESUME`
|
||||
|
|
@ -205,6 +205,8 @@ Using :monitoring-event:`BRANCH_LEFT` and :monitoring-event:`BRANCH_RIGHT`
|
|||
events will give much better performance as they can be disabled
|
||||
independently.
|
||||
|
||||
.. _monitoring-ancillary-events:
|
||||
|
||||
Ancillary events
|
||||
''''''''''''''''
|
||||
|
||||
|
|
@ -226,7 +228,7 @@ Other events
|
|||
''''''''''''
|
||||
|
||||
Other events are not necessarily tied to a specific location in the
|
||||
program and cannot be individually disabled via :data:`DISABLE`.
|
||||
program and cannot be individually disabled per location.
|
||||
|
||||
The other events that can be monitored are:
|
||||
|
||||
|
|
@ -234,6 +236,12 @@ The other events that can be monitored are:
|
|||
* :monitoring-event:`PY_UNWIND`
|
||||
* :monitoring-event:`RAISE`
|
||||
* :monitoring-event:`EXCEPTION_HANDLED`
|
||||
* :monitoring-event:`RERAISE`
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
Other events can now be turned on and disabled on a per code object
|
||||
basis. Returning :data:`DISABLE` from a callback disables the event
|
||||
for the entire code object (for the current tool).
|
||||
|
||||
|
||||
The STOP_ITERATION event
|
||||
|
|
@ -247,8 +255,7 @@ raise an exception unless it would be visible to other code.
|
|||
|
||||
To allow tools to monitor for real exceptions without slowing down generators
|
||||
and coroutines, the :monitoring-event:`STOP_ITERATION` event is provided.
|
||||
:monitoring-event:`STOP_ITERATION` can be locally disabled, unlike
|
||||
:monitoring-event:`RAISE`.
|
||||
:monitoring-event:`STOP_ITERATION` can be locally disabled.
|
||||
|
||||
Note that the :monitoring-event:`STOP_ITERATION` event and the
|
||||
:monitoring-event:`RAISE` event for a :exc:`StopIteration` exception are
|
||||
|
|
@ -314,15 +321,14 @@ location by returning :data:`sys.monitoring.DISABLE` from a callback function.
|
|||
This does not change which events are set, or any other code locations for the
|
||||
same event.
|
||||
|
||||
Disabling events for specific locations is very important for high
|
||||
performance monitoring. For example, a program can be run under a
|
||||
debugger with no overhead if the debugger disables all monitoring
|
||||
except for a few breakpoints.
|
||||
:ref:`Other events <monitoring-event-global>` can be disabled on a per code
|
||||
object basis by returning :data:`sys.monitoring.DISABLE` from a callback
|
||||
function. This disables the event for the entire code object (for the current
|
||||
tool).
|
||||
|
||||
If :data:`DISABLE` is returned by a callback for a
|
||||
:ref:`global event <monitoring-event-global>`, :exc:`ValueError` will be raised
|
||||
by the interpreter in a non-specific location (that is, no traceback will be
|
||||
provided).
|
||||
Disabling events for specific locations is very important for high performance
|
||||
monitoring. For example, a program can be run under a debugger with no overhead
|
||||
if the debugger disables all monitoring except for a few breakpoints.
|
||||
|
||||
.. function:: restart_events() -> None
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 110 KiB |
|
|
@ -28,7 +28,7 @@ type can be determined by checking the ``exact_type`` property on the
|
|||
**undefined** when providing invalid Python code and it can change at any
|
||||
point.
|
||||
|
||||
Tokenizing Input
|
||||
Tokenizing input
|
||||
----------------
|
||||
|
||||
The primary entry point is a :term:`generator`:
|
||||
|
|
@ -146,7 +146,7 @@ function it uses to do this is available:
|
|||
|
||||
.. _tokenize-cli:
|
||||
|
||||
Command-Line Usage
|
||||
Command-line usage
|
||||
------------------
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
|
@ -173,8 +173,12 @@ The following options are accepted:
|
|||
If :file:`filename.py` is specified its contents are tokenized to stdout.
|
||||
Otherwise, tokenization is performed on stdin.
|
||||
|
||||
.. versionadded:: next
|
||||
Output is in color by default and can be
|
||||
:ref:`controlled using environment variables <using-on-controlling-color>`.
|
||||
|
||||
Examples
|
||||
------------------
|
||||
--------
|
||||
|
||||
Example of a script rewriter that transforms float literals into Decimal
|
||||
objects::
|
||||
|
|
@ -227,7 +231,7 @@ Example of tokenizing from the command line. The script::
|
|||
|
||||
will be tokenized to the following output where the first column is the range
|
||||
of the line/column coordinates where the token is found, the second column is
|
||||
the name of the token, and the final column is the value of the token (if any)
|
||||
the name of the token, and the final column is the value of the token (if any):
|
||||
|
||||
.. code-block:: shell-session
|
||||
|
||||
|
|
|
|||
|
|
@ -1174,7 +1174,8 @@ These can be used as types in annotations. They all support subscription using
|
|||
or transforms parameters of another
|
||||
callable. Usage is in the form
|
||||
``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate``
|
||||
is currently only valid when used as the first argument to a :ref:`Callable <annotating-callables>`.
|
||||
is valid when used in :ref:`Callable <annotating-callables>` type hints
|
||||
and when instantiating user-defined generic classes with :class:`ParamSpec` parameters.
|
||||
The last parameter to ``Concatenate`` must be a :class:`ParamSpec` or
|
||||
ellipsis (``...``).
|
||||
|
||||
|
|
@ -1980,7 +1981,7 @@ without the dedicated syntax, as documented below.
|
|||
|
||||
.. _typevartuple:
|
||||
|
||||
.. class:: TypeVarTuple(name, *, default=typing.NoDefault)
|
||||
.. class:: TypeVarTuple(name, *, bound=None, covariant=False, contravariant=False, infer_variance=False, default=typing.NoDefault)
|
||||
|
||||
Type variable tuple. A specialized form of :ref:`type variable <typevar>`
|
||||
that enables *variadic* generics.
|
||||
|
|
@ -2090,6 +2091,24 @@ without the dedicated syntax, as documented below.
|
|||
|
||||
The name of the type variable tuple.
|
||||
|
||||
.. attribute:: __covariant__
|
||||
|
||||
Whether the type variable tuple has been explicitly marked as covariant.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. attribute:: __contravariant__
|
||||
|
||||
Whether the type variable tuple has been explicitly marked as contravariant.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. attribute:: __infer_variance__
|
||||
|
||||
Whether the type variable tuple's variance should be inferred by type checkers.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. attribute:: __default__
|
||||
|
||||
The default value of the type variable tuple, or :data:`typing.NoDefault` if it
|
||||
|
|
@ -2116,6 +2135,11 @@ without the dedicated syntax, as documented below.
|
|||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
Type variable tuples created with ``covariant=True`` or
|
||||
``contravariant=True`` can be used to declare covariant or contravariant
|
||||
generic types. The ``bound`` argument is also accepted, similar to
|
||||
:class:`TypeVar`, but its actual semantics are yet to be decided.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
|
@ -2127,6 +2151,11 @@ without the dedicated syntax, as documented below.
|
|||
|
||||
Support for default values was added.
|
||||
|
||||
.. versionchanged:: 3.15
|
||||
|
||||
Added support for the ``bound``, ``covariant``, ``contravariant``, and
|
||||
``infer_variance`` parameters.
|
||||
|
||||
.. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False, default=typing.NoDefault)
|
||||
|
||||
Parameter specification variable. A specialized version of
|
||||
|
|
@ -2196,6 +2225,20 @@ without the dedicated syntax, as documented below.
|
|||
|
||||
The name of the parameter specification.
|
||||
|
||||
.. attribute:: __covariant__
|
||||
|
||||
Whether the parameter specification has been explicitly marked as covariant.
|
||||
|
||||
.. attribute:: __contravariant__
|
||||
|
||||
Whether the parameter specification has been explicitly marked as contravariant.
|
||||
|
||||
.. attribute:: __infer_variance__
|
||||
|
||||
Whether the parameter specification's variance should be inferred by type checkers.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. attribute:: __default__
|
||||
|
||||
The default value of the parameter specification, or :data:`typing.NoDefault` if it
|
||||
|
|
@ -3358,6 +3401,36 @@ Functions and decorators
|
|||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. decorator:: disjoint_base
|
||||
|
||||
Decorator to mark a class as a disjoint base.
|
||||
|
||||
Type checkers do not allow child classes of a disjoint base ``C`` to
|
||||
inherit from other disjoint bases that are not parent or child classes of ``C``.
|
||||
|
||||
For example::
|
||||
|
||||
@disjoint_base
|
||||
class Disjoint1: pass
|
||||
|
||||
@disjoint_base
|
||||
class Disjoint2: pass
|
||||
|
||||
class Disjoint3(Disjoint1, Disjoint2): pass # Type checker error
|
||||
|
||||
Type checkers can use knowledge of disjoint bases to detect unreachable code
|
||||
and determine when two types can overlap.
|
||||
|
||||
The corresponding runtime concept is a solid base (see :ref:`multiple-inheritance`).
|
||||
Classes that are solid bases at runtime can be marked with ``@disjoint_base`` in stub files.
|
||||
Users may also mark other classes as disjoint bases to indicate to type checkers that
|
||||
multiple inheritance with other disjoint bases should not be allowed.
|
||||
|
||||
Note that the concept of a solid base is a CPython implementation
|
||||
detail, and the exact set of standard library classes that are
|
||||
disjoint bases at runtime may change in future versions of Python.
|
||||
|
||||
.. versionadded:: next
|
||||
|
||||
.. decorator:: type_check_only
|
||||
|
||||
|
|
@ -3380,13 +3453,13 @@ Functions and decorators
|
|||
Introspection helpers
|
||||
---------------------
|
||||
|
||||
.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False)
|
||||
.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False, *, format=Format.VALUE)
|
||||
|
||||
Return a dictionary containing type hints for a function, method, module,
|
||||
class object, or other callable object.
|
||||
|
||||
This is often the same as ``obj.__annotations__``, but this function makes
|
||||
the following changes to the annotations dictionary:
|
||||
This is often the same as :func:`annotationlib.get_annotations`, but this
|
||||
function makes the following changes to the annotations dictionary:
|
||||
|
||||
* Forward references encoded as string literals or :class:`ForwardRef`
|
||||
objects are handled by evaluating them in *globalns*, *localns*, and
|
||||
|
|
@ -3400,17 +3473,15 @@ Introspection helpers
|
|||
annotations from ``C``'s base classes with those on ``C`` directly. This
|
||||
is done by traversing :attr:`C.__mro__ <type.__mro__>` and iteratively
|
||||
combining
|
||||
``__annotations__`` dictionaries. Annotations on classes appearing
|
||||
earlier in the :term:`method resolution order` always take precedence over
|
||||
annotations on classes appearing later in the method resolution order.
|
||||
:term:`annotations <variable annotation>` of each base class. Annotations
|
||||
on classes appearing earlier in the :term:`method resolution order` always
|
||||
take precedence over annotations on classes appearing later in the method
|
||||
resolution order.
|
||||
* The function recursively replaces all occurrences of
|
||||
``Annotated[T, ...]``, ``Required[T]``, ``NotRequired[T]``, and ``ReadOnly[T]``
|
||||
with ``T``, unless *include_extras* is set to ``True`` (see
|
||||
:class:`Annotated` for more information).
|
||||
|
||||
See also :func:`annotationlib.get_annotations`, a lower-level function that
|
||||
returns annotations more directly.
|
||||
|
||||
.. caution::
|
||||
|
||||
This function may execute arbitrary code contained in annotations.
|
||||
|
|
@ -3418,11 +3489,12 @@ Introspection helpers
|
|||
|
||||
.. note::
|
||||
|
||||
If any forward references in the annotations of *obj* are not resolvable
|
||||
or are not valid Python code, this function will raise an exception
|
||||
such as :exc:`NameError`. For example, this can happen with imported
|
||||
:ref:`type aliases <type-aliases>` that include forward references,
|
||||
or with names imported under :data:`if TYPE_CHECKING <TYPE_CHECKING>`.
|
||||
If :attr:`Format.VALUE <annotationlib.Format.VALUE>` is used and any
|
||||
forward references in the annotations of *obj* are not resolvable, a
|
||||
:exc:`NameError` exception is raised. For example, this can happen
|
||||
with names imported under :data:`if TYPE_CHECKING <TYPE_CHECKING>`.
|
||||
More generally, any kind of exception can be raised if an annotation
|
||||
contains invalid Python code.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -3440,6 +3512,10 @@ Introspection helpers
|
|||
if a default value equal to ``None`` was set.
|
||||
Now the annotation is returned unchanged.
|
||||
|
||||
.. versionchanged:: 3.14
|
||||
Added the ``format`` parameter. See the documentation on
|
||||
:func:`annotationlib.get_annotations` for more information.
|
||||
|
||||
.. versionchanged:: 3.14
|
||||
Calling :func:`get_type_hints` on instances is no longer supported.
|
||||
Some instances were accepted in earlier versions as an undocumented
|
||||
|
|
@ -3797,7 +3873,7 @@ Aliases to other concrete types
|
|||
Match
|
||||
|
||||
Deprecated aliases corresponding to the return types from
|
||||
:func:`re.compile` and :func:`re.match`.
|
||||
:func:`re.compile` and :func:`re.search`.
|
||||
|
||||
These types (and the corresponding functions) are generic over
|
||||
:data:`AnyStr`. ``Pattern`` can be specialised as ``Pattern[str]`` or
|
||||
|
|
|
|||
|
|
@ -1223,9 +1223,9 @@ Test cases
|
|||
| :meth:`assertNotRegex(s, r) | ``not r.search(s)`` | 3.2 |
|
||||
| <TestCase.assertNotRegex>` | | |
|
||||
+---------------------------------------+--------------------------------+--------------+
|
||||
| :meth:`assertCountEqual(a, b) | *a* and *b* have the same | 3.2 |
|
||||
| <TestCase.assertCountEqual>` | elements in the same number, | |
|
||||
| | regardless of their order. | |
|
||||
| :meth:`assertCountEqual(a, b) | *a* contains the same elements | 3.2 |
|
||||
| <TestCase.assertCountEqual>` | as *b*, regardless of their | |
|
||||
| | order. | |
|
||||
+---------------------------------------+--------------------------------+--------------+
|
||||
| :meth:`assertStartsWith(a, b) | ``a.startswith(b)`` | 3.14 |
|
||||
| <TestCase.assertStartsWith>` | | |
|
||||
|
|
|
|||
|
|
@ -858,7 +858,7 @@ A literal pattern corresponds to most
|
|||
: | "None"
|
||||
: | "True"
|
||||
: | "False"
|
||||
signed_number: ["-"] NUMBER
|
||||
signed_number: ["+" | "-"] NUMBER
|
||||
|
||||
The rule ``strings`` and the token ``NUMBER`` are defined in the
|
||||
:doc:`standard Python grammar <./grammar>`. Triple-quoted strings are
|
||||
|
|
|
|||
|
|
@ -926,6 +926,7 @@ Attribute assignment updates the module's namespace dictionary, e.g.,
|
|||
single: __doc__ (module attribute)
|
||||
single: __annotations__ (module attribute)
|
||||
single: __annotate__ (module attribute)
|
||||
single: __lazy_modules__ (module attribute)
|
||||
pair: module; namespace
|
||||
|
||||
.. _import-mod-attrs:
|
||||
|
|
@ -1121,6 +1122,20 @@ the following writable attributes:
|
|||
|
||||
.. versionadded:: 3.14
|
||||
|
||||
.. attribute:: module.__lazy_modules__
|
||||
|
||||
A container (an object implementing :meth:`~object.__contains__`) of fully
|
||||
qualified module name strings. When defined
|
||||
at module scope, any regular :keyword:`import` statement in that module whose
|
||||
target module name appears in this container is treated as a
|
||||
:ref:`lazy import <lazy-imports>`, as if the :keyword:`lazy` keyword had
|
||||
been used. Imports inside functions, class bodies, or
|
||||
:keyword:`try`/:keyword:`except`/:keyword:`finally` blocks are unaffected.
|
||||
|
||||
See :ref:`lazy-modules-compat` for details and examples.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
Module dictionaries
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
@ -1461,7 +1476,6 @@ indirectly) to mutable objects.
|
|||
single: co_filename (code object attribute)
|
||||
single: co_firstlineno (code object attribute)
|
||||
single: co_flags (code object attribute)
|
||||
single: co_lnotab (code object attribute)
|
||||
single: co_name (code object attribute)
|
||||
single: co_names (code object attribute)
|
||||
single: co_nlocals (code object attribute)
|
||||
|
|
@ -1534,14 +1548,6 @@ Special read-only attributes
|
|||
* - .. attribute:: codeobject.co_firstlineno
|
||||
- The line number of the first line of the function
|
||||
|
||||
* - .. attribute:: codeobject.co_lnotab
|
||||
- A string encoding the mapping from :term:`bytecode` offsets to line
|
||||
numbers. For details, see the source code of the interpreter.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
This attribute of code objects is deprecated, and may be removed in
|
||||
Python 3.15.
|
||||
|
||||
* - .. attribute:: codeobject.co_stacksize
|
||||
- The required stack size of the code object
|
||||
|
||||
|
|
|
|||
|
|
@ -920,6 +920,56 @@ See :pep:`810` for the full specification of lazy imports.
|
|||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. _lazy-modules-compat:
|
||||
|
||||
Compatibility via ``__lazy_modules__``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. index::
|
||||
single: __lazy_modules__
|
||||
|
||||
As an alternative to using the :keyword:`lazy` keyword, a module can opt
|
||||
into lazy loading for specific imports by defining a module-level
|
||||
:attr:`~module.__lazy_modules__` variable. When present, it must be a
|
||||
container of fully qualified module name strings. Any regular (non-``lazy``)
|
||||
:keyword:`import` statement at module scope whose target appears in
|
||||
:attr:`!__lazy_modules__` is treated as a lazy import, exactly as if the
|
||||
:keyword:`lazy` keyword had been used.
|
||||
|
||||
This provides a way to enable lazy loading for specific dependencies without
|
||||
changing individual ``import`` statements. This is useful when supporting
|
||||
Python versions older than 3.15 while using lazy imports in 3.15+::
|
||||
|
||||
__lazy_modules__ = ["json", "pathlib"]
|
||||
|
||||
import json # loaded lazily (name is in __lazy_modules__)
|
||||
import os # loaded eagerly (name not in __lazy_modules__)
|
||||
|
||||
import pathlib # loaded lazily
|
||||
|
||||
Relative imports are resolved to their absolute name before the lookup, so
|
||||
:attr:`!__lazy_modules__` must always contain fully qualified module names.
|
||||
|
||||
For ``from``-style imports, the relevant name is the module following
|
||||
``from``, not the names of its members::
|
||||
|
||||
# In mypackage/mymodule.py
|
||||
__lazy_modules__ = ["mypackage", "mypackage.sub.utils"]
|
||||
|
||||
from . import helper # loaded lazily: . resolves to mypackage
|
||||
from .sub.utils import func # loaded lazily: .sub.utils resolves to mypackage.sub.utils
|
||||
import json # loaded eagerly (not in __lazy_modules__)
|
||||
|
||||
Imports inside functions, class bodies, or
|
||||
:keyword:`try`/:keyword:`except`/:keyword:`finally` blocks are always eager,
|
||||
regardless of :attr:`!__lazy_modules__`.
|
||||
|
||||
Setting ``-X lazy_imports=none`` (or the :envvar:`PYTHON_LAZY_IMPORTS`
|
||||
environment variable to ``none``) overrides :attr:`!__lazy_modules__` and
|
||||
forces all imports to be eager.
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
.. _future:
|
||||
|
||||
Future statements
|
||||
|
|
|
|||
|
|
@ -249,18 +249,17 @@ def _stable_abi_annotation(
|
|||
reftype="ref",
|
||||
refexplicit="False",
|
||||
)
|
||||
struct_abi_kind = record.struct_abi_kind
|
||||
if struct_abi_kind in {"opaque", "members"}:
|
||||
ref_node += nodes.Text(sphinx_gettext("Limited API"))
|
||||
else:
|
||||
ref_node += nodes.Text(sphinx_gettext("Stable ABI"))
|
||||
ref_node += nodes.Text(sphinx_gettext("Stable ABI"))
|
||||
emph_node += ref_node
|
||||
struct_abi_kind = record.struct_abi_kind
|
||||
if struct_abi_kind == "opaque":
|
||||
emph_node += nodes.Text(" " + sphinx_gettext("(as an opaque struct)"))
|
||||
elif struct_abi_kind == "full-abi":
|
||||
emph_node += nodes.Text(
|
||||
" " + sphinx_gettext("(including all members)")
|
||||
)
|
||||
elif struct_abi_kind in {"members", "abi3t-opaque"}:
|
||||
emph_node += nodes.Text(" " + sphinx_gettext("(see below)"))
|
||||
if record.ifdef_note:
|
||||
emph_node += nodes.Text(f" {record.ifdef_note}")
|
||||
if stable_added == "3.2":
|
||||
|
|
@ -271,11 +270,7 @@ def _stable_abi_annotation(
|
|||
" " + sphinx_gettext("since version %s") % stable_added
|
||||
)
|
||||
emph_node += nodes.Text(".")
|
||||
if struct_abi_kind == "members":
|
||||
msg = " " + sphinx_gettext(
|
||||
"(Only some members are part of the stable ABI.)"
|
||||
)
|
||||
emph_node += nodes.Text(msg)
|
||||
|
||||
return emph_node
|
||||
|
||||
|
||||
|
|
@ -378,6 +373,33 @@ def run(self) -> list[nodes.Node]:
|
|||
return [node]
|
||||
|
||||
|
||||
class VersionHexCheatsheet(SphinxDirective):
|
||||
"""Show results of Py_PACK_VERSION(3, x) for a few relevant Python versions
|
||||
|
||||
This is useful for defining version before Python.h is included.
|
||||
It should auto-update with the version being documented, so it must be an
|
||||
extension.
|
||||
"""
|
||||
|
||||
has_content = False
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
|
||||
def run(self) -> list[nodes.Node]:
|
||||
content = [
|
||||
".. code-block:: c",
|
||||
"",
|
||||
]
|
||||
current_minor = int(self.config.version.removeprefix('3.'))
|
||||
for minor in range(current_minor - 5, current_minor + 1):
|
||||
value = (3 << 24) | (minor << 16)
|
||||
content.append(f' {value:#x} /* Py_PACK_VERSION(3.{minor}) */')
|
||||
node = nodes.paragraph()
|
||||
self.state.nested_parse(StringList(content), 0, node)
|
||||
return [node]
|
||||
|
||||
|
||||
class CorrespondingTypeSlot(SphinxDirective):
|
||||
"""Type slot annotations
|
||||
|
||||
|
|
@ -443,6 +465,7 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
|||
app.add_config_value("stable_abi_file", "", "env", types={str})
|
||||
app.add_config_value("threadsafety_file", "", "env", types={str})
|
||||
app.add_directive("limited-api-list", LimitedAPIList)
|
||||
app.add_directive("version-hex-cheatsheet", VersionHexCheatsheet)
|
||||
app.add_directive("corresponding-type-slot", CorrespondingTypeSlot)
|
||||
app.connect("builder-inited", init_annotations)
|
||||
app.connect("doctree-read", add_annotations)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
import re
|
||||
|
||||
from docutils import nodes
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains.changeset import (
|
||||
VersionChange,
|
||||
versionlabel_classes,
|
||||
|
|
@ -11,6 +13,7 @@
|
|||
)
|
||||
from sphinx.locale import _ as sphinx_gettext
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from docutils.nodes import Node
|
||||
from sphinx.application import Sphinx
|
||||
|
|
@ -73,6 +76,76 @@ def run(self) -> list[Node]:
|
|||
versionlabel_classes[self.name] = ""
|
||||
|
||||
|
||||
class SoftDeprecated(PyVersionChange):
|
||||
"""Directive for soft deprecations that auto-links to the glossary term.
|
||||
|
||||
Usage::
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
Use :func:`new_thing` instead.
|
||||
|
||||
Renders as: "Soft deprecated since version 3.15: Use new_thing() instead."
|
||||
with "Soft deprecated" linking to the glossary definition.
|
||||
"""
|
||||
|
||||
_TERM_RE = re.compile(r":term:`([^`]+)`")
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
versionlabels[self.name] = sphinx_gettext(
|
||||
":term:`Soft deprecated` since version %s"
|
||||
)
|
||||
versionlabel_classes[self.name] = "soft-deprecated"
|
||||
try:
|
||||
result = super().run()
|
||||
finally:
|
||||
versionlabels[self.name] = ""
|
||||
versionlabel_classes[self.name] = ""
|
||||
|
||||
for node in result:
|
||||
# Add "versionchanged" class so existing theme CSS applies
|
||||
node["classes"] = node.get("classes", []) + ["versionchanged"]
|
||||
# Replace the plain-text "Soft deprecated" with a glossary reference
|
||||
for inline in node.findall(nodes.inline):
|
||||
if "versionmodified" in inline.get("classes", []):
|
||||
self._add_glossary_link(inline)
|
||||
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def _add_glossary_link(cls, inline: nodes.inline) -> None:
|
||||
"""Replace :term:`soft deprecated` text with a cross-reference to the
|
||||
'Soft deprecated' glossary entry."""
|
||||
for child in inline.children:
|
||||
if not isinstance(child, nodes.Text):
|
||||
continue
|
||||
|
||||
text = str(child)
|
||||
match = cls._TERM_RE.search(text)
|
||||
if match is None:
|
||||
continue
|
||||
|
||||
ref = addnodes.pending_xref(
|
||||
"",
|
||||
nodes.Text(match.group(1)),
|
||||
refdomain="std",
|
||||
reftype="term",
|
||||
reftarget="soft deprecated",
|
||||
refwarn=True,
|
||||
)
|
||||
|
||||
start, end = match.span()
|
||||
new_nodes: list[nodes.Node] = []
|
||||
if start > 0:
|
||||
new_nodes.append(nodes.Text(text[:start]))
|
||||
new_nodes.append(ref)
|
||||
if end < len(text):
|
||||
new_nodes.append(nodes.Text(text[end:]))
|
||||
|
||||
child.parent.replace(child, new_nodes)
|
||||
break
|
||||
|
||||
|
||||
def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
# Override Sphinx's directives with support for 'next'
|
||||
app.add_directive("versionadded", PyVersionChange, override=True)
|
||||
|
|
@ -83,6 +156,9 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
|||
# Register the ``.. deprecated-removed::`` directive
|
||||
app.add_directive("deprecated-removed", DeprecatedRemoved)
|
||||
|
||||
# Register the ``.. soft-deprecated::`` directive
|
||||
app.add_directive("soft-deprecated", SoftDeprecated)
|
||||
|
||||
return {
|
||||
"version": "1.0",
|
||||
"parallel_read_safe": True,
|
||||
|
|
|
|||
|
|
@ -1 +1,7 @@
|
|||
# HTML IDs excluded from the check-html-ids.py check.
|
||||
|
||||
# Remove from here in 3.16
|
||||
c-api/allocation.html: deprecated-aliases
|
||||
c-api/file.html: deprecated-api
|
||||
|
||||
library/asyncio-task.html: terminating-a-task-group
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
{% trans %}Deprecated since version %s, will be removed in version %s{% endtrans %}
|
||||
{% trans %}Deprecated since version %s, removed in version %s{% endtrans %}
|
||||
{% trans %}:term:`Soft deprecated` since version %s{% endtrans %}
|
||||
|
||||
In docsbuild-scripts, when rewriting indexsidebar.html with actual versions:
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Adding Python to an Android app
|
|||
Most app developers should use one of the following tools, which will provide a
|
||||
much easier experience:
|
||||
|
||||
* `Briefcase <https://briefcase.readthedocs.io>`__, from the BeeWare project
|
||||
* `Briefcase <https://briefcase.beeware.org>`__, from the BeeWare project
|
||||
* `Buildozer <https://buildozer.readthedocs.io>`__, from the Kivy project
|
||||
* `Chaquopy <https://chaquo.com/chaquopy>`__
|
||||
* `pyqtdeploy <https://www.riverbankcomputing.com/static/Docs/pyqtdeploy/>`__
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,21 @@ Linker options
|
|||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. option:: --enable-static-libpython-for-interpreter
|
||||
|
||||
Do not link the Python interpreter binary (``python3``) against the
|
||||
shared Python library; instead, statically link the interpreter
|
||||
against ``libpython`` as if ``--enable-shared`` had not been used,
|
||||
but continue to build the shared ``libpython`` (for use by other
|
||||
programs).
|
||||
|
||||
This option does nothing if ``--enable-shared`` is not used.
|
||||
|
||||
The default (when ``-enable-shared`` is used) is to link the Python
|
||||
interpreter against the built shared library.
|
||||
|
||||
.. versionadded:: next
|
||||
|
||||
|
||||
Libraries options
|
||||
-----------------
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue