diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml
index 0fe754bb071ea3..d0efa77f93052b 100644
--- a/.azure-pipelines/ci.yml
+++ b/.azure-pipelines/ci.yml
@@ -1,14 +1,14 @@
variables:
coverage: false
-trigger: ['master', '3.9', '3.8', '3.7']
+trigger: ['main', '3.10', '3.9', '3.8', '3.7']
jobs:
- job: Prebuild
displayName: Pre-build checks
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
steps:
- template: ./prebuild-checks.yml
@@ -20,7 +20,7 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
steps:
- template: ./docs-steps.yml
@@ -40,7 +40,7 @@ jobs:
testRunPlatform: macos
pool:
- vmImage: macos-10.14
+ vmImage: macos-10.15
steps:
- template: ./macos-steps.yml
@@ -52,12 +52,12 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
variables:
testRunTitle: '$(build.sourceBranchName)-linux'
testRunPlatform: linux
- openssl_version: 1.1.1k
+ openssl_version: 1.1.1n
steps:
- template: ./posix-steps.yml
@@ -78,12 +78,12 @@ jobs:
)
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
variables:
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
testRunPlatform: linux-coverage
- openssl_version: 1.1.1k
+ openssl_version: 1.1.1n
steps:
- template: ./posix-steps.yml
diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml
index 2d32e6d49bcc0e..a4f32460c7ea02 100644
--- a/.azure-pipelines/pr.yml
+++ b/.azure-pipelines/pr.yml
@@ -1,14 +1,14 @@
variables:
coverage: false
-pr: ['master', '3.9', '3.8', '3.7']
+pr: ['main', '3.10', '3.9', '3.8', '3.7']
jobs:
- job: Prebuild
displayName: Pre-build checks
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
steps:
- template: ./prebuild-checks.yml
@@ -20,7 +20,7 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
steps:
- template: ./docs-steps.yml
@@ -38,7 +38,7 @@ jobs:
testRunPlatform: macos
pool:
- vmImage: macos-10.14
+ vmImage: macos-10.15
steps:
- template: ./macos-steps.yml
@@ -52,12 +52,12 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
variables:
testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
testRunPlatform: linux
- openssl_version: 1.1.1k
+ openssl_version: 1.1.1n
steps:
- template: ./posix-steps.yml
@@ -78,12 +78,12 @@ jobs:
)
pool:
- vmImage: ubuntu-18.04
+ vmImage: ubuntu-20.04
variables:
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
testRunPlatform: linux-coverage
- openssl_version: 1.1.1k
+ openssl_version: 1.1.1n
steps:
- template: ./posix-steps.yml
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000000000..81445d2d79c739
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*.{py,c,cpp,h,rst,md,yml}]
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+
+[*.{py,c,cpp,h}]
+indent_size = 4
+
+[*.yml]
+indent_size = 2
diff --git a/.gitattributes b/.gitattributes
index c66e765266382f..be369d2a5c63c4 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -40,11 +40,8 @@ PCbuild/readme.txt text eol=crlf
PC/readme.txt text eol=crlf
# Generated files
-# https://github.com/github/linguist#generated-code
-Modules/clinic/*.h linguist-generated=true
-Objects/clinic/*.h linguist-generated=true
-PC/clinic/*.h linguist-generated=true
-Python/clinic/*.h linguist-generated=true
+# https://github.com/github/linguist/blob/master/docs/overrides.md
+**/clinic/*.h linguist-generated=true
Python/importlib.h linguist-generated=true
Python/importlib_external.h linguist-generated=true
Include/internal/pycore_ast.h linguist-generated=true
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 5b86d39dc9c259..173b957b108c60 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -96,7 +96,7 @@ Lib/ast.py @isidentical
/Lib/unittest/test/testmock/* @cjw296
# SQLite 3
-**/*sqlite* @berkerpeksag
+**/*sqlite* @berkerpeksag @erlend-aasland
# subprocess
/Lib/subprocess.py @gpshead
@@ -128,7 +128,7 @@ Lib/ast.py @isidentical
**/*idlelib* @terryjreedy
-**/*typing* @gvanrossum @ilevkivskyi
+**/*typing* @gvanrossum @Fidget-Spinner @JelleZijlstra
**/*asyncore @giampaolo
**/*asynchat @giampaolo
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index 28aea946623cc5..82ae4ca8c30977 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -10,9 +10,8 @@ https://devguide.python.org/#status-of-python-branches
## Reporting a Vulnerability
Please read the guidelines on reporting security issues [on the
-official website](
-https://www.python.org/news/security/#reporting-security-issues-in-python
-) for instructions on how to report a security-related problem to
+official website](https://www.python.org/dev/security/) for
+instructions on how to report a security-related problem to
the Python team responsibly.
To reach the response team, email `security at python dot org`.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 41200bb957e47c..b98514aaf94522 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,12 +7,14 @@ on:
push:
branches:
- master
+ - 3.10
- 3.9
- 3.8
- 3.7
pull_request:
branches:
- master
+ - 3.10
- 3.9
- 3.8
- 3.7
@@ -25,7 +27,7 @@ jobs:
run_tests: ${{ steps.check.outputs.run_tests }}
run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Check for source changes
id: check
run: |
@@ -51,16 +53,59 @@ jobs:
git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo '::set-output name=run_ssl_tests::true' || true
fi
+ check_abi:
+ name: 'Check if the ABI has changed'
+ runs-on: ubuntu-20.04
+ needs: check_source
+ if: needs.check_source.outputs.run_tests == 'true'
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
+ - name: Install Dependencies
+ run: |
+ sudo ./.github/workflows/posix-deps-apt.sh
+ sudo apt-get install -yq abigail-tools
+ - name: Build CPython
+ env:
+ CFLAGS: -g3 -O0
+ run: |
+ # Build Python with the libpython dynamic library
+ ./configure --enable-shared
+ make -j4
+ - name: Check for changes in the ABI
+ run: |
+ make check-abidump
+ if [ $? -neq 0 ] ; then
+ echo "Generated ABI file is not up to date."
+ echo "Please, add the release manager of this branch as a reviewer of this PR."
+ echo ""
+ echo "To learn more about this check, please visit: https://devguide.python.org/setup/?highlight=abi#regenerate-the-abi-dump"
+ echo ""
+ exit 1
+ fi
+
check_generated_files:
name: 'Check if generated files are up to date'
runs-on: ubuntu-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v3
- name: Install Dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
+ - name: Add ccache to PATH
+ run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
+ - name: Configure ccache action
+ uses: hendrikmuhs/ccache-action@v1
+ - name: Check Autoconf version 2.69 and aclocal 1.16.3
+ run: |
+ grep "Generated by GNU Autoconf 2.69" configure
+ grep "aclocal 1.16.3" aclocal.m4
+ grep -q "runstatedir" configure
+ grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4
+ - name: Regenerate autoconf files
+ run: docker run --rm -v $(pwd):/src quay.io/tiran/cpython_autoconf:269
- name: Build CPython
run: |
# Build Python with the libpython dynamic library
@@ -71,9 +116,10 @@ jobs:
run: |
changes=$(git status --porcelain)
# Check for changes in regenerated files
- if ! test -z "$changes"
- then
- echo "Generated files not up to date. Perhaps you forgot to run make regen-all ;)"
+ if test -n "$changes"; then
+ echo "Generated files not up to date."
+ echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)"
+ echo "configure files must be regenerated with a specific, unpatched version of autoconf."
echo "$changes"
exit 1
fi
@@ -87,8 +133,10 @@ jobs:
runs-on: windows-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
+ env:
+ IncludeUwp: 'true'
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Build CPython
run: .\PCbuild\build.bat -e -p Win32
- name: Display build info
@@ -101,8 +149,10 @@ jobs:
runs-on: windows-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
+ env:
+ IncludeUwp: 'true'
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Register MSVC problem matcher
run: echo "::add-matcher::.github/problem-matchers/msvc.json"
- name: Build CPython
@@ -117,10 +167,16 @@ jobs:
runs-on: macos-latest
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
+ env:
+ PYTHONSTRICTEXTENSIONBUILD: 1
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
+ - name: Prepare homebrew environment variables
+ run: |
+ echo "LDFLAGS=-L$(brew --prefix tcl-tk)/lib" >> $GITHUB_ENV
+ echo "PKG_CONFIG_PATH=$(brew --prefix openssl@1.1)/lib/pkgconfig:$(brew --prefix tcl-tk)/lib/pkgconfig" >> $GITHUB_ENV
- name: Configure CPython
- run: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-dev
+ run: ./configure --with-pydebug --prefix=/opt/python-dev
- name: Build CPython
run: make -j4
- name: Display build info
@@ -134,9 +190,10 @@ jobs:
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:
- OPENSSL_VER: 1.1.1k
+ OPENSSL_VER: 1.1.1n
+ PYTHONSTRICTEXTENSIONBUILD: 1
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install Dependencies
@@ -148,7 +205,7 @@ jobs:
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
- name: 'Restore OpenSSL build'
id: cache-openssl
- uses: actions/cache@v2.1.4
+ uses: actions/cache@v3.0.2
with:
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
@@ -177,14 +234,14 @@ jobs:
strategy:
fail-fast: false
matrix:
- openssl_ver: [1.1.1k, 3.0.0-alpha15]
+ openssl_ver: [1.1.1n, 3.0.2]
env:
OPENSSL_VER: ${{ matrix.openssl_ver }}
MULTISSL_DIR: ${{ github.workspace }}/multissl
OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}
LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install Dependencies
@@ -196,7 +253,7 @@ jobs:
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
- name: 'Restore OpenSSL build'
id: cache-openssl
- uses: actions/cache@v2.1.4
+ uses: actions/cache@v3.0.2
with:
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml
index 182eb7ce571671..201098a635799a 100644
--- a/.github/workflows/build_msi.yml
+++ b/.github/workflows/build_msi.yml
@@ -4,6 +4,7 @@ on:
push:
branches:
- master
+ - 3.10
- 3.9
- 3.8
- 3.7
@@ -12,6 +13,7 @@ on:
pull_request:
branches:
- master
+ - 3.10
- 3.9
- 3.8
- 3.7
@@ -23,7 +25,7 @@ jobs:
name: 'Windows (x86) Installer'
runs-on: windows-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Build CPython installer
run: .\Tools\msi\build.bat -x86
@@ -31,6 +33,6 @@ jobs:
name: 'Windows (x64) Installer'
runs-on: windows-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Build CPython installer
run: .\Tools\msi\build.bat -x64
diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml
index 8924fc992e25e6..e2501589d6e6a5 100644
--- a/.github/workflows/doc.yml
+++ b/.github/workflows/doc.yml
@@ -12,6 +12,7 @@ on:
pull_request:
branches:
- master
+ - 3.10
- 3.9
- 3.8
- 3.7
@@ -24,9 +25,41 @@ jobs:
name: 'Docs'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Register Sphinx problem matcher
run: echo "::add-matcher::.github/problem-matchers/sphinx.json"
+ - name: 'Set up Python'
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3'
+ cache: 'pip'
+ cache-dependency-path: 'Doc/requirements.txt'
+ - name: 'Install build dependencies'
+ run: make -C Doc/ venv
+ - name: 'Check documentation'
+ run: make -C Doc/ suspicious
+ - name: 'Build HTML documentation'
+ run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html
+ - name: 'Upload'
+ uses: actions/upload-artifact@v3
+ with:
+ name: doc-html
+ path: Doc/build/html
+
+ # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release
+ doctest:
+ name: 'Doctest'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Register Sphinx problem matcher
+ run: echo "::add-matcher::.github/problem-matchers/sphinx.json"
+ - uses: actions/cache@v3
+ with:
+ path: ~/.cache/pip
+ key: ubuntu-doc-${{ hashFiles('Doc/requirements.txt') }}
+ restore-keys: |
+ ubuntu-doc-
- name: 'Install Dependencies'
run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican
- name: 'Configure CPython'
@@ -35,10 +68,6 @@ jobs:
run: make -j4
- name: 'Install build dependencies'
run: make -C Doc/ PYTHON=../python venv
- - name: 'Build documentation'
- run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" doctest html suspicious
- - name: 'Upload'
- uses: actions/upload-artifact@v2.2.2
- with:
- name: doc-html
- path: Doc/build/html
+ # Use "xvfb-run" since some doctest tests open GUI windows
+ - name: 'Run documentation doctest'
+ run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" doctest
diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh
index 56cc70edf60001..0119843e47eeb1 100755
--- a/.github/workflows/posix-deps-apt.sh
+++ b/.github/workflows/posix-deps-apt.sh
@@ -9,6 +9,7 @@ apt-get -yq install \
libbz2-dev \
libffi-dev \
libgdbm-dev \
+ libgdbm-compat-dev \
liblzma-dev \
libncurses5-dev \
libreadline6-dev \
diff --git a/.github/workflows/regen-abidump.sh b/.github/workflows/regen-abidump.sh
new file mode 100644
index 00000000000000..251bb3857ecfcb
--- /dev/null
+++ b/.github/workflows/regen-abidump.sh
@@ -0,0 +1,8 @@
+set -ex
+
+export DEBIAN_FRONTEND=noninteractive
+./.github/workflows/posix-deps-apt.sh
+apt-get install -yq abigail-tools python3
+export CFLAGS="-g3 -O0"
+./configure --enable-shared && make
+make regen-abidump
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 26806fad814f1a..4a08ef0d8dac5f 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -13,7 +13,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/stale@v3
+ - name: "Check PRs"
+ uses: actions/stale@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity.'
diff --git a/.github/workflows/verify-ensurepip-wheels.yml b/.github/workflows/verify-ensurepip-wheels.yml
new file mode 100644
index 00000000000000..61e3d1adf534d5
--- /dev/null
+++ b/.github/workflows/verify-ensurepip-wheels.yml
@@ -0,0 +1,28 @@
+name: Verify bundled pip and setuptools
+
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - 'Lib/ensurepip/_bundled/**'
+ - '.github/workflows/verify-ensurepip-wheels.yml'
+ - 'Tools/scripts/verify_ensurepip_wheels.py'
+ pull_request:
+ paths:
+ - 'Lib/ensurepip/_bundled/**'
+ - '.github/workflows/verify-ensurepip-wheels.yml'
+ - 'Tools/scripts/verify_ensurepip_wheels.py'
+
+permissions:
+ contents: read
+
+jobs:
+ verify:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: '3'
+ - name: Compare checksums of bundled pip and setuptools to ones published on PyPI
+ run: ./Tools/scripts/verify_ensurepip_wheels.py
diff --git a/.gitignore b/.gitignore
index 80dcf34bf47a6f..09d08c8050cb2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ gmon.out
.coverage
.mypy_cache/
.pytest_cache/
+.DS_Store
*.exe
!Lib/distutils/command/*.exe
@@ -60,6 +61,15 @@ Lib/test/data/*
!Lib/test/data/README
/Makefile
/Makefile.pre
+Mac/Makefile
+Mac/PythonLauncher/Info.plist
+Mac/PythonLauncher/Makefile
+Mac/PythonLauncher/Python Launcher
+Mac/PythonLauncher/Python Launcher.app/*
+Mac/Resources/app/Info.plist
+Mac/Resources/framework/Info.plist
+Mac/pythonw
+/*.framework/
Misc/python.pc
Misc/python-embed.pc
Misc/python-config.sh
@@ -102,6 +112,8 @@ Tools/unicode/data/
/config.log
/config.status
/config.status.lineno
+# hendrikmuhs/ccache-action@v1
+/.ccache
/platform
/profile-clean-stamp
/profile-run-stamp
@@ -124,3 +136,9 @@ Tools/ssl/win32
# Ignore ./python binary on Unix but still look into ./Python/ directory.
/python
!/Python/
+
+# Artifacts generated by 3.11 lying around when switching branches:
+/_bootstrap_python
+/Programs/_freeze_module
+/Python/deepfreeze/
+/Python/frozen_modules/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 1112a0b266227b..ee6cabe5ae0da3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,6 +18,7 @@ env:
# Set rpath with env var instead of -Wl,-rpath linker flag
# OpenSSL ignores LDFLAGS when linking bin/openssl
- LD_RUN_PATH="${OPENSSL_DIR}/lib"
+ - PYTHONSTRICTEXTENSIONBUILD=1
branches:
only:
diff --git a/Doc/Makefile b/Doc/Makefile
index f113dd06539869..939498e548a069 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -17,7 +17,7 @@ SPHINXERRORHANDLING = -W
PAPEROPT_a4 = -D latex_elements.papersize=a4paper
PAPEROPT_letter = -D latex_elements.papersize=letterpaper
-ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) \
+ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) -j auto \
$(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES)
.PHONY: help build html htmlhelp latex text texinfo changes linkcheck \
@@ -137,14 +137,22 @@ pydoc-topics: build
htmlview: html
$(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
-clean:
- -rm -rf build/* $(VENVDIR)/*
+clean: clean-venv
+ -rm -rf build/*
+
+clean-venv:
+ rm -rf $(VENVDIR)
venv:
- $(PYTHON) -m venv $(VENVDIR)
- $(VENVDIR)/bin/python3 -m pip install -U pip setuptools
- $(VENVDIR)/bin/python3 -m pip install -r requirements.txt
- @echo "The venv has been created in the $(VENVDIR) directory"
+ @if [ -d $(VENVDIR) ] ; then \
+ echo "venv already exists."; \
+ echo "To recreate it, remove it first with \`make clean-venv'."; \
+ else \
+ $(PYTHON) -m venv $(VENVDIR); \
+ $(VENVDIR)/bin/python3 -m pip install -U pip setuptools; \
+ $(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \
+ echo "The venv has been created in the $(VENVDIR) directory"; \
+ fi
dist:
rm -rf dist
diff --git a/Doc/README.rst b/Doc/README.rst
index 380ea4fa9b26ad..7e8a27b4066d87 100644
--- a/Doc/README.rst
+++ b/Doc/README.rst
@@ -28,28 +28,31 @@ install the tools into there.
Using make
----------
-To get started on UNIX, you can create a virtual environment with the command ::
+To get started on UNIX, you can create a virtual environment and build
+documentation with the commands::
make venv
-
-That will install all the tools necessary to build the documentation. Assuming
-the virtual environment was created in the ``venv`` directory (the default;
-configurable with the VENVDIR variable), you can run the following command to
-build the HTML output files::
-
make html
-By default, if the virtual environment is not created, the Makefile will
-look for instances of sphinxbuild and blurb installed on your process PATH
-(configurable with the SPHINXBUILD and BLURB variables).
+The virtual environment in the ``venv`` directory will contain all the tools
+necessary to build the documentation downloaded and installed from PyPI.
+If you'd like to create the virtual environment in a different location,
+you can specify it using the ``VENVDIR`` variable.
+
+You can also skip creating the virtual environment altogether, in which case
+the Makefile will look for instances of ``sphinxbuild`` and ``blurb``
+installed on your process ``PATH`` (configurable with the ``SPHINXBUILD`` and
+``BLURB`` variables).
On Windows, we try to emulate the Makefile as closely as possible with a
``make.bat`` file. If you need to specify the Python interpreter to use,
-set the PYTHON environment variable instead.
+set the PYTHON environment variable.
Available make targets are:
-* "clean", which removes all build files.
+* "clean", which removes all build files and the virtual environment.
+
+* "clean-venv", which removes the virtual environment directory.
* "venv", which creates a virtual environment with all necessary tools
installed.
diff --git a/Doc/about.rst b/Doc/about.rst
index 3ea311fa629dd2..f0b908487b2d09 100644
--- a/Doc/about.rst
+++ b/Doc/about.rst
@@ -23,9 +23,8 @@ Many thanks go to:
and writer of much of the content;
* the `Docutils `_ project for creating
reStructuredText and the Docutils suite;
-* Fredrik Lundh for his `Alternative Python Reference
- `_ project from which Sphinx got many good
- ideas.
+* Fredrik Lundh for his Alternative Python Reference project from which Sphinx
+ got many good ideas.
Contributors to the Python Documentation
diff --git a/Doc/bugs.rst b/Doc/bugs.rst
index a17f04d26fa40b..0feddeb5793fcd 100644
--- a/Doc/bugs.rst
+++ b/Doc/bugs.rst
@@ -35,13 +35,17 @@ though it may take a while to be processed.
`Helping with Documentation `_
Comprehensive guide for individuals that are interested in contributing to Python documentation.
+ `Documentation Translations `_
+ A list of GitHub pages for documentation translation and their primary contacts.
+
+
.. _using-the-tracker:
Using the Python issue tracker
==============================
Bug reports for Python itself should be submitted via the Python Bug Tracker
-(https://bugs.python.org/). The bug tracker offers a Web form which allows
+(https://bugs.python.org/). The bug tracker offers a web form which allows
pertinent information to be entered and submitted to the developers.
The first step in filing a report is to determine whether the problem has
@@ -80,7 +84,7 @@ taken on the bug.
Article which goes into some detail about how to create a useful bug report.
This describes what kind of information is useful and why it is useful.
- `Bug Report Writing Guidelines `_
+ `Bug Writing Guidelines `_
Information about writing a good bug report. Some of this is specific to the
Mozilla project, but describes general good practices.
diff --git a/Doc/c-api/abstract.rst b/Doc/c-api/abstract.rst
index f5df09fa7fd786..1823f9d70c79f3 100644
--- a/Doc/c-api/abstract.rst
+++ b/Doc/c-api/abstract.rst
@@ -24,3 +24,4 @@ but whose items have not been set to some non-\ ``NULL`` value yet.
mapping.rst
iter.rst
buffer.rst
+ objbuffer.rst
diff --git a/Doc/c-api/apiabiversion.rst b/Doc/c-api/apiabiversion.rst
index b8a8f2ff886219..04050f7dabe172 100644
--- a/Doc/c-api/apiabiversion.rst
+++ b/Doc/c-api/apiabiversion.rst
@@ -6,34 +6,57 @@
API and ABI Versioning
***********************
-``PY_VERSION_HEX`` is the Python version number encoded in a single integer.
-
-For example if the ``PY_VERSION_HEX`` is set to ``0x030401a2``, the underlying
-version information can be found by treating it as a 32 bit number in
-the following manner:
-
- +-------+-------------------------+------------------------------------------------+
- | Bytes | Bits (big endian order) | Meaning |
- +=======+=========================+================================================+
- | ``1`` | ``1-8`` | ``PY_MAJOR_VERSION`` (the ``3`` in |
- | | | ``3.4.1a2``) |
- +-------+-------------------------+------------------------------------------------+
- | ``2`` | ``9-16`` | ``PY_MINOR_VERSION`` (the ``4`` in |
- | | | ``3.4.1a2``) |
- +-------+-------------------------+------------------------------------------------+
- | ``3`` | ``17-24`` | ``PY_MICRO_VERSION`` (the ``1`` in |
- | | | ``3.4.1a2``) |
- +-------+-------------------------+------------------------------------------------+
- | ``4`` | ``25-28`` | ``PY_RELEASE_LEVEL`` (``0xA`` for alpha, |
- | | | ``0xB`` for beta, ``0xC`` for release |
- | | | candidate and ``0xF`` for final), in this |
- | | | case it is alpha. |
- +-------+-------------------------+------------------------------------------------+
- | | ``29-32`` | ``PY_RELEASE_SERIAL`` (the ``2`` in |
- | | | ``3.4.1a2``, zero for final releases) |
- +-------+-------------------------+------------------------------------------------+
-
-Thus ``3.4.1a2`` is hexversion ``0x030401a2``.
+CPython exposes its version number in the following macros.
+Note that these correspond to the version code is **built** with,
+not necessarily the version used at **run time**.
-All the given macros are defined in :source:`Include/patchlevel.h`.
+See :ref:`stable` for a discussion of API and ABI stability across versions.
+
+.. c:macro:: PY_MAJOR_VERSION
+
+ The ``3`` in ``3.4.1a2``.
+
+.. c:macro:: PY_MINOR_VERSION
+
+ The ``4`` in ``3.4.1a2``.
+
+.. c:macro:: PY_MICRO_VERSION
+
+ The ``1`` in ``3.4.1a2``.
+
+.. c:macro:: PY_RELEASE_LEVEL
+
+ The ``a`` in ``3.4.1a2``.
+ This can be ``0xA`` for alpha, ``0xB`` for beta, ``0xC`` for release
+ candidate or ``0xF`` for final.
+.. c:macro:: PY_RELEASE_SERIAL
+
+ The ``2`` in ``3.4.1a2``. Zero for final releases.
+
+.. c:macro:: PY_VERSION_HEX
+
+ The Python version number encoded in a single integer.
+
+ The underlying version information can be found by treating it as a 32 bit
+ number in the following manner:
+
+ +-------+-------------------------+-------------------------+--------------------------+
+ | Bytes | Bits (big endian order) | Meaning | Value for ``3.4.1a2`` |
+ +=======+=========================+=========================+==========================+
+ | 1 | 1-8 | ``PY_MAJOR_VERSION`` | ``0x03`` |
+ +-------+-------------------------+-------------------------+--------------------------+
+ | 2 | 9-16 | ``PY_MINOR_VERSION`` | ``0x04`` |
+ +-------+-------------------------+-------------------------+--------------------------+
+ | 3 | 17-24 | ``PY_MICRO_VERSION`` | ``0x01`` |
+ +-------+-------------------------+-------------------------+--------------------------+
+ | 4 | 25-28 | ``PY_RELEASE_LEVEL`` | ``0xA`` |
+ + +-------------------------+-------------------------+--------------------------+
+ | | 29-32 | ``PY_RELEASE_SERIAL`` | ``0x2`` |
+ +-------+-------------------------+-------------------------+--------------------------+
+
+ Thus ``3.4.1a2`` is hexversion ``0x030401a2`` and ``3.10.0`` is
+ hexversion ``0x030a00f0``.
+
+
+All the given macros are defined in :source:`Include/patchlevel.h`.
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 1d93b35dc1c884..926e5249347f84 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -286,7 +286,7 @@ Numbers
Convert a Python integer to a C :c:type:`unsigned long long`
without overflow checking.
-``n`` (:class:`int`) [Py_ssize_t]
+``n`` (:class:`int`) [:c:type:`Py_ssize_t`]
Convert a Python integer to a C :c:type:`Py_ssize_t`.
``c`` (:class:`bytes` or :class:`bytearray` of length 1) [char]
@@ -613,7 +613,7 @@ Building values
``K`` (:class:`int`) [unsigned long long]
Convert a C :c:type:`unsigned long long` to a Python integer object.
- ``n`` (:class:`int`) [Py_ssize_t]
+ ``n`` (:class:`int`) [:c:type:`Py_ssize_t`]
Convert a C :c:type:`Py_ssize_t` to a Python integer.
``c`` (:class:`bytes` of length 1) [char]
diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst
index 30bcfc7cf9f500..85a7d1373c2a81 100644
--- a/Doc/c-api/bytearray.rst
+++ b/Doc/c-api/bytearray.rst
@@ -42,8 +42,6 @@ Direct API functions
Return a new bytearray object from any object, *o*, that implements the
:ref:`buffer protocol `.
- .. XXX expand about the buffer protocol, at least somewhere
-
.. c:function:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len)
diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst
index de65701037a7c1..ffbfb5a61b44bb 100644
--- a/Doc/c-api/bytes.rst
+++ b/Doc/c-api/bytes.rst
@@ -5,7 +5,7 @@
Bytes Objects
-------------
-These functions raise :exc:`TypeError` when expecting a bytes parameter and are
+These functions raise :exc:`TypeError` when expecting a bytes parameter and
called with a non-bytes parameter.
.. index:: object: bytes
@@ -84,8 +84,8 @@ called with a non-bytes parameter.
| :attr:`%lu` | unsigned long | Equivalent to |
| | | ``printf("%lu")``. [1]_ |
+-------------------+---------------+--------------------------------+
- | :attr:`%zd` | Py_ssize_t | Equivalent to |
- | | | ``printf("%zd")``. [1]_ |
+ | :attr:`%zd` | :c:type:`\ | Equivalent to |
+ | | Py_ssize_t` | ``printf("%zd")``. [1]_ |
+-------------------+---------------+--------------------------------+
| :attr:`%zu` | size_t | Equivalent to |
| | | ``printf("%zu")``. [1]_ |
diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst
index 31dc9c8031fdb6..13ef8b217a1622 100644
--- a/Doc/c-api/call.rst
+++ b/Doc/c-api/call.rst
@@ -26,7 +26,7 @@ This convention is not only used by *tp_call*:
:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_init`
also pass arguments this way.
-To call an object, use :c:func:`PyObject_Call` or other
+To call an object, use :c:func:`PyObject_Call` or another
:ref:`call API `.
@@ -144,8 +144,6 @@ Vectorcall Support API
However, the function ``PyVectorcall_NARGS`` should be used to allow
for future extensions.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.8
.. c:function:: vectorcallfunc PyVectorcall_Function(PyObject *op)
@@ -158,8 +156,6 @@ Vectorcall Support API
This is mostly useful to check whether or not *op* supports vectorcall,
which can be done by checking ``PyVectorcall_Function(op) != NULL``.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.8
.. c:function:: PyObject* PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)
@@ -172,8 +168,6 @@ Vectorcall Support API
It does not check the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag
and it does not fall back to ``tp_call``.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.8
@@ -185,7 +179,7 @@ Object Calling API
Various functions are available for calling a Python object.
Each converts its arguments to a convention supported by the called object –
either *tp_call* or vectorcall.
-In order to do as litle conversion as possible, pick one that best fits
+In order to do as little conversion as possible, pick one that best fits
the format of data you have available.
The following table summarizes the available functions;
@@ -256,8 +250,6 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.9
@@ -343,8 +335,6 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.9
@@ -357,8 +347,6 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.9
@@ -372,8 +360,6 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.9
.. c:function:: PyObject* PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)
@@ -388,8 +374,6 @@ please see individual documentation for details.
already has a dictionary ready to use for the keyword arguments,
but not a tuple for the positional arguments.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.9
.. c:function:: PyObject* PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames)
@@ -410,8 +394,6 @@ please see individual documentation for details.
Return the result of the call on success, or raise an exception and return
*NULL* on failure.
- This function is not part of the :ref:`limited API `.
-
.. versionadded:: 3.9
diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst
index e2ea766b3a32a7..c25894681bca35 100644
--- a/Doc/c-api/complex.rst
+++ b/Doc/c-api/complex.rst
@@ -46,9 +46,9 @@ pointers. This is consistent throughout the API.
:c:type:`Py_complex` representation.
-.. c:function:: Py_complex _Py_c_neg(Py_complex complex)
+.. c:function:: Py_complex _Py_c_neg(Py_complex num)
- Return the negation of the complex number *complex*, using the C
+ Return the negation of the complex number *num*, using the C
:c:type:`Py_complex` representation.
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index c1d9fa1b41a3fe..84224dcca523b9 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -115,3 +115,4 @@ Other Objects
coro.rst
contextvars.rst
datetime.rst
+ typehints.rst
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 21c508dc30ae22..fc90fa2b746e36 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -100,7 +100,7 @@ For convenience, some of these functions will always return a
This is the most common way to set the error indicator. The first argument
specifies the exception type; it is normally one of the standard exceptions,
e.g. :c:data:`PyExc_RuntimeError`. You need not increment its reference count.
- The second argument is an error message; it is decoded from ``'utf-8``'.
+ The second argument is an error message; it is decoded from ``'utf-8'``.
.. c:function:: void PyErr_SetObject(PyObject *type, PyObject *value)
@@ -253,6 +253,14 @@ For convenience, some of these functions will always return a
.. versionadded:: 3.3
+.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
+
+ Much like :c:func:`PyErr_SetImportError` but this function allows for
+ specifying a subclass of :exc:`ImportError` to raise.
+
+ .. versionadded:: 3.6
+
+
.. c:function:: void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
Set file, line, and offset information for the current exception. If the
@@ -273,7 +281,7 @@ For convenience, some of these functions will always return a
.. c:function:: void PyErr_SyntaxLocation(const char *filename, int lineno)
- Like :c:func:`PyErr_SyntaxLocationEx`, but the col_offset parameter is
+ Like :c:func:`PyErr_SyntaxLocationEx`, but the *col_offset* parameter is
omitted.
@@ -320,19 +328,12 @@ an error value).
:mod:`warnings` module and the :option:`-W` option in the command line
documentation. There is no C API for warning control.
-.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
-
- Much like :c:func:`PyErr_SetImportError` but this function allows for
- specifying a subclass of :exc:`ImportError` to raise.
-
- .. versionadded:: 3.6
-
.. c:function:: int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry)
Issue a warning message with explicit control over all warning attributes. This
is a straightforward wrapper around the Python function
- :func:`warnings.warn_explicit`, see there for more information. The *module*
+ :func:`warnings.warn_explicit`; see there for more information. The *module*
and *registry* arguments may be set to ``NULL`` to get the default effect
described there.
@@ -440,7 +441,7 @@ Querying the error indicator
error indicator.
-.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)
+.. c:function:: void PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below
can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is
@@ -888,11 +889,11 @@ the variables:
+-----------------------------------------+---------------------------------+----------+
| C Name | Python Name | Notes |
+=========================================+=================================+==========+
-| :c:data:`PyExc_BaseException` | :exc:`BaseException` | \(1) |
+| :c:data:`PyExc_BaseException` | :exc:`BaseException` | [1]_ |
+-----------------------------------------+---------------------------------+----------+
-| :c:data:`PyExc_Exception` | :exc:`Exception` | \(1) |
+| :c:data:`PyExc_Exception` | :exc:`Exception` | [1]_ |
+-----------------------------------------+---------------------------------+----------+
-| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) |
+| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | [1]_ |
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_AssertionError` | :exc:`AssertionError` | |
+-----------------------------------------+---------------------------------+----------+
@@ -938,7 +939,7 @@ the variables:
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | |
+-----------------------------------------+---------------------------------+----------+
-| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) |
+| :c:data:`PyExc_LookupError` | :exc:`LookupError` | [1]_ |
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_MemoryError` | :exc:`MemoryError` | |
+-----------------------------------------+---------------------------------+----------+
@@ -950,7 +951,7 @@ the variables:
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | |
+-----------------------------------------+---------------------------------+----------+
-| :c:data:`PyExc_OSError` | :exc:`OSError` | \(1) |
+| :c:data:`PyExc_OSError` | :exc:`OSError` | [1]_ |
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_OverflowError` | :exc:`OverflowError` | |
+-----------------------------------------+---------------------------------+----------+
@@ -960,7 +961,7 @@ the variables:
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_RecursionError` | :exc:`RecursionError` | |
+-----------------------------------------+---------------------------------+----------+
-| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) |
+| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | |
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | |
+-----------------------------------------+---------------------------------+----------+
@@ -1025,7 +1026,7 @@ These are compatibility aliases to :c:data:`PyExc_OSError`:
+-------------------------------------+----------+
| :c:data:`PyExc_IOError` | |
+-------------------------------------+----------+
-| :c:data:`PyExc_WindowsError` | \(3) |
+| :c:data:`PyExc_WindowsError` | [2]_ |
+-------------------------------------+----------+
.. versionchanged:: 3.3
@@ -1033,10 +1034,10 @@ These are compatibility aliases to :c:data:`PyExc_OSError`:
Notes:
-(1)
+.. [1]
This is a base class for other standard exceptions.
-(2)
+.. [2]
Only defined on Windows; protect code that uses this by testing that the
preprocessor macro ``MS_WINDOWS`` is defined.
@@ -1066,7 +1067,7 @@ the variables:
+------------------------------------------+---------------------------------+----------+
| C Name | Python Name | Notes |
+==========================================+=================================+==========+
-| :c:data:`PyExc_Warning` | :exc:`Warning` | \(1) |
+| :c:data:`PyExc_Warning` | :exc:`Warning` | [3]_ |
+------------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_BytesWarning` | :exc:`BytesWarning` | |
+------------------------------------------+---------------------------------+----------+
@@ -1094,5 +1095,5 @@ the variables:
Notes:
-(1)
+.. [3]
This is a base class for other standard warning categories.
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index 55ed9d4f7fad48..8c90d1e8991c10 100644
--- a/Doc/c-api/gcsupport.rst
+++ b/Doc/c-api/gcsupport.rst
@@ -33,6 +33,26 @@ Constructors for container types must conform to two rules:
#. Once all the fields which may contain references to other containers are
initialized, it must call :c:func:`PyObject_GC_Track`.
+Similarly, the deallocator for the object must conform to a similar pair of
+rules:
+
+#. Before fields which refer to other containers are invalidated,
+ :c:func:`PyObject_GC_UnTrack` must be called.
+
+#. The object's memory must be deallocated using :c:func:`PyObject_GC_Del`.
+
+ .. warning::
+ If a type adds the Py_TPFLAGS_HAVE_GC, then it *must* implement at least
+ a :c:member:`~PyTypeObject.tp_traverse` handler or explicitly use one
+ from its subclass or subclasses.
+
+ When calling :c:func:`PyType_Ready` or some of the APIs that indirectly
+ call it like :c:func:`PyType_FromSpecWithBases` or
+ :c:func:`PyType_FromSpec` the interpreter will automatically populate the
+ :c:member:`~PyTypeObject.tp_flags`, :c:member:`~PyTypeObject.tp_traverse`
+ and :c:member:`~PyTypeObject.tp_clear` fields if the type inherits from a
+ class that implements the garbage collector protocol and the child class
+ does *not* include the :const:`Py_TPFLAGS_HAVE_GC` flag.
.. c:function:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type)
@@ -88,14 +108,6 @@ Constructors for container types must conform to two rules:
.. versionadded:: 3.9
-Similarly, the deallocator for the object must conform to a similar pair of
-rules:
-
-#. Before fields which refer to other containers are invalidated,
- :c:func:`PyObject_GC_UnTrack` must be called.
-
-#. The object's memory must be deallocated using :c:func:`PyObject_GC_Del`.
-
.. c:function:: void PyObject_GC_Del(void *op)
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index c6fc33076f0f51..d2ae6b6d4e4711 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -299,4 +299,8 @@ Importing Modules
field; failure to provide the sentinel value can result in a memory fault.
Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to
extend the internal table. In the event of failure, no modules are added to the
- internal table. This should be called before :c:func:`Py_Initialize`.
+ internal table. This must be called before :c:func:`Py_Initialize`.
+
+ If Python is initialized multiple times, :c:func:`PyImport_AppendInittab` or
+ :c:func:`PyImport_ExtendInittab` must be called before each Python
+ initialization.
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 0f759732b35ea8..a44442a5015550 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -473,7 +473,7 @@ Process-wide parameters
(set by :c:func:`Py_SetProgramName` above) and some environment variables.
The returned string consists of a series of directory names separated by a
platform dependent delimiter character. The delimiter character is ``':'``
- on Unix and Mac OS X, ``';'`` on Windows. The returned string points into
+ on Unix and macOS, ``';'`` on Windows. The returned string points into
static storage; the caller should not modify its value. The list
:data:`sys.path` is initialized with this value on interpreter startup; it
can be (and usually is) modified later to change the search path for loading
@@ -500,7 +500,7 @@ Process-wide parameters
default search path but uses the one provided instead. This is useful if
Python is embedded by an application that has full knowledge of the location
of all modules. The path components should be separated by the platform
- dependent delimiter character, which is ``':'`` on Unix and Mac OS X, ``';'``
+ dependent delimiter character, which is ``':'`` on Unix and macOS, ``';'``
on Windows.
This also causes :data:`sys.executable` to be set to the program
@@ -529,7 +529,7 @@ Process-wide parameters
.. index:: single: version (in module sys)
The first word (up to the first space character) is the current Python version;
- the first three characters are the major and minor version separated by a
+ the first characters are the major and minor version separated by a
period. The returned string points into static storage; the caller should not
modify its value. The value is available to Python code as :data:`sys.version`.
@@ -541,7 +541,7 @@ Process-wide parameters
Return the platform identifier for the current platform. On Unix, this is
formed from the "official" name of the operating system, converted to lower
case, followed by the major revision number; e.g., for Solaris 2.x, which is
- also known as SunOS 5.x, the value is ``'sunos5'``. On Mac OS X, it is
+ also known as SunOS 5.x, the value is ``'sunos5'``. On macOS, it is
``'darwin'``. On Windows, it is ``'win'``. The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as ``sys.platform``.
@@ -1725,7 +1725,7 @@ is not possible due to its implementation being opaque at build time.
argument is `NULL`.
.. note::
- A freed key becomes a dangling pointer, you should reset the key to
+ A freed key becomes a dangling pointer. You should reset the key to
`NULL`.
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index de85029481185a..2b6da2a7810bc4 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -16,13 +16,13 @@ There are two kinds of configuration:
* The :ref:`Python Configuration ` can be used to build a
customized Python which behaves as the regular Python. For example,
- environments variables and command line arguments are used to configure
+ environment variables and command line arguments are used to configure
Python.
* The :ref:`Isolated Configuration ` can be used to embed
Python into an application. It isolates Python from the system. For example,
- environments variables are ignored, the LC_CTYPE locale is left unchanged and
- no signal handler is registred.
+ environment variables are ignored, the LC_CTYPE locale is left unchanged and
+ no signal handler is registered.
The :c:func:`Py_RunMain` function can be used to write a customized Python
program.
@@ -634,7 +634,7 @@ PyConfig
.. c:member:: int dump_refs
- Dump Python refererences?
+ Dump Python references?
If non-zero, dump all objects which are still alive at exit.
@@ -689,14 +689,13 @@ PyConfig
* ``"utf-8"`` if :c:member:`PyPreConfig.utf8_mode` is non-zero.
* ``"ascii"`` if Python detects that ``nl_langinfo(CODESET)`` announces
- the ASCII encoding (or Roman8 encoding on HP-UX), whereas the
- ``mbstowcs()`` function decodes from a different encoding (usually
- Latin1).
+ the ASCII encoding, whereas the ``mbstowcs()`` function
+ decodes from a different encoding (usually Latin1).
* ``"utf-8"`` if ``nl_langinfo(CODESET)`` returns an empty string.
* Otherwise, use the :term:`locale encoding`:
``nl_langinfo(CODESET)`` result.
- At Python statup, the encoding name is normalized to the Python codec
+ At Python startup, the encoding name is normalized to the Python codec
name. For example, ``"ANSI_X3.4-1968"`` is replaced with ``"ascii"``.
See also the :c:member:`~PyConfig.filesystem_errors` member.
@@ -1193,7 +1192,10 @@ The caller is responsible to handle exceptions (error or exit) using
If :c:func:`PyImport_FrozenModules`, :c:func:`PyImport_AppendInittab` or
:c:func:`PyImport_ExtendInittab` are used, they must be set or called after
-Python preinitialization and before the Python initialization.
+Python preinitialization and before the Python initialization. If Python is
+initialized multiple times, :c:func:`PyImport_AppendInittab` or
+:c:func:`PyImport_ExtendInittab` must be called before each Python
+initialization.
The current configuration (``PyConfig`` type) is stored in
``PyInterpreterState.config``.
@@ -1284,7 +1286,7 @@ Isolated Configuration
isolate Python from the system. For example, to embed Python into an
application.
-This configuration ignores global configuration variables, environments
+This configuration ignores global configuration variables, environment
variables, command line arguments (:c:member:`PyConfig.argv` is not parsed)
and user site directory. The C standard streams (ex: ``stdout``) and the
LC_CTYPE locale are left unchanged. Signal handlers are not installed.
@@ -1429,7 +1431,7 @@ Multi-Phase Initialization Private Provisional API
==================================================
This section is a private provisional API introducing multi-phase
-initialization, the core feature of the :pep:`432`:
+initialization, the core feature of :pep:`432`:
* "Core" initialization phase, "bare minimum Python":
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index 2d85d30702df9c..083f6d32c79f83 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -502,6 +502,13 @@ data attributes of a new object type, and another is used to describe the value
of a complex number. These will be discussed together with the functions that
use them.
+.. c:type:: Py_ssize_t
+
+ A signed integral type such that ``sizeof(Py_ssize_t) == sizeof(size_t)``.
+ C99 doesn't define such a thing directly (size_t is an unsigned integral type).
+ See :pep:`353` for details. ``PY_SSIZE_T_MAX`` is the largest positive value
+ of type :c:type:`Py_ssize_t`.
+
.. _api-exceptions:
diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst
index 63290e0a7f0bf7..434d2021cea8e6 100644
--- a/Doc/c-api/iter.rst
+++ b/Doc/c-api/iter.rst
@@ -9,22 +9,23 @@ There are two functions specifically for working with iterators.
.. c:function:: int PyIter_Check(PyObject *o)
- Return non-zero if the object *o* supports the iterator protocol, and ``0``
- otherwise. This function always succeeds.
+ Return non-zero if the object *o* can be safely passed to
+ :c:func:`PyIter_Next`, and ``0`` otherwise. This function always succeeds.
-.. c:function:: int PyAiter_Check(PyObject *o)
+.. c:function:: int PyAIter_Check(PyObject *o)
- Returns non-zero if the object 'obj' provides :class:`AsyncIterator`
- protocols, and ``0`` otherwise. This function always succeeds.
+ Return non-zero if the object *o* provides the :class:`AsyncIterator`
+ protocol, and ``0`` otherwise. This function always succeeds.
.. versionadded:: 3.10
.. c:function:: PyObject* PyIter_Next(PyObject *o)
- Return the next value from the iteration *o*. The object must be an iterator
- (it is up to the caller to check this). If there are no remaining values,
- returns ``NULL`` with no exception set. If an error occurs while retrieving
- the item, returns ``NULL`` and passes along the exception.
+ Return the next value from the iterator *o*. The object must be an iterator
+ according to :c:func:`PyIter_Check` (it is up to the caller to check this).
+ If there are no remaining values, returns ``NULL`` with no exception set.
+ If an error occurs while retrieving the item, returns ``NULL`` and passes
+ along the exception.
To write a loop which iterates over an iterator, the C code should look
something like this::
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 4201490286b82f..620344e71373b2 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -41,7 +41,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
Return a new :c:type:`PyLongObject` object from *v*, or ``NULL`` on failure.
The current implementation keeps an array of integer objects for all integers
- between ``-5`` and ``256``, when you create an int in that range you actually
+ between ``-5`` and ``256``. When you create an int in that range you actually
just get back a reference to the existing object.
diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst
index 682160d1475c1c..3c9d282c6d0ab0 100644
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -11,10 +11,10 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
.. c:function:: int PyMapping_Check(PyObject *o)
- Return ``1`` if the object provides mapping protocol or supports slicing,
+ Return ``1`` if the object provides the mapping protocol or supports slicing,
and ``0`` otherwise. Note that it returns ``1`` for Python classes with
- a :meth:`__getitem__` method since in general case it is impossible to
- determine what type of keys it supports. This function always succeeds.
+ a :meth:`__getitem__` method, since in general it is impossible to
+ determine what type of keys the class supports. This function always succeeds.
.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst
index efddc6f7be5e71..f17d24bda589c1 100644
--- a/Doc/c-api/memory.rst
+++ b/Doc/c-api/memory.rst
@@ -306,7 +306,7 @@ memory from the Python heap.
.. note::
There is no guarantee that the memory returned by these allocators can be
- successfully casted to a Python object when intercepting the allocating
+ successfully cast to a Python object when intercepting the allocating
functions in this domain by the methods described in
the :ref:`Customize Memory Allocators ` section.
@@ -403,7 +403,7 @@ Customize Memory Allocators
.. c:type:: PyMemAllocatorEx
Structure used to describe a memory block allocator. The structure has
- four fields:
+ the following fields:
+----------------------------------------------------------+---------------------------------------+
| Field | Meaning |
@@ -488,7 +488,7 @@ Customize Memory Allocators
Debug hooks on the Python memory allocators
===========================================
-When :ref:`Python is built is debug mode `, the
+When :ref:`Python is built in debug mode `, the
:c:func:`PyMem_SetupDebugHooks` function is called at the :ref:`Python
preinitialization ` to setup debug hooks on Python memory allocators
to detect memory errors.
diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst
index 23852251dfe020..6e7e1e21aa93f2 100644
--- a/Doc/c-api/method.rst
+++ b/Doc/c-api/method.rst
@@ -27,7 +27,7 @@ to bind a :c:data:`PyCFunction` to a class object. It replaces the former call
.. c:function:: PyObject* PyInstanceMethod_New(PyObject *func)
- Return a new instance method object, with *func* being any callable object
+ Return a new instance method object, with *func* being any callable object.
*func* is the function that will be called when the instance method is
called.
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index a2541afb685c30..94c8d9f981713f 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -221,6 +221,12 @@ or request "multi-phase initialization" by returning the definition struct itsel
than 0 and the module state (as returned by :c:func:`PyModule_GetState`)
is ``NULL``.
+ Like :c:member:`PyTypeObject.tp_clear`, this function is not *always*
+ called before a module is deallocated. For example, when reference
+ counting is enough to determine that an object is no longer used,
+ the cyclic garbage collector is not involved and
+ :c:member:`~PyModuleDef.m_free` is called directly.
+
.. versionchanged:: 3.9
No longer called before the module state is allocated.
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
index 37979bb506bcfa..70b91f8c2d0ca1 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -44,7 +44,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2)
Return the floor of *o1* divided by *o2*, or ``NULL`` on failure. This is
- equivalent to the "classic" division of integers.
+ the equivalent of the Python expression ``o1 // o2``.
.. c:function:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2)
@@ -53,7 +53,7 @@ Number Protocol
*o2*, or ``NULL`` on failure. The return value is "approximate" because binary
floating point numbers are approximate; it is not possible to represent all real
numbers in base two. This function can return a floating point value when
- passed two integers.
+ passed two integers. This is the equivalent of the Python expression ``o1 / o2``.
.. c:function:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2)
@@ -180,6 +180,7 @@ Number Protocol
floating point numbers are approximate; it is not possible to represent all real
numbers in base two. This function can return a floating point value when
passed two integers. The operation is done *in-place* when *o1* supports it.
+ This is the equivalent of the Python statement ``o1 /= o2``.
.. c:function:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2)
@@ -272,11 +273,11 @@ Number Protocol
.. c:function:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc)
- Returns *o* converted to a Py_ssize_t value if *o* can be interpreted as an
+ Returns *o* converted to a :c:type:`Py_ssize_t` value if *o* can be interpreted as an
integer. If the call fails, an exception is raised and ``-1`` is returned.
If *o* can be converted to a Python int but the attempt to
- convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the
+ convert to a :c:type:`Py_ssize_t` value would raise an :exc:`OverflowError`, then the
*exc* argument is the type of exception that will be raised (usually
:exc:`IndexError` or :exc:`OverflowError`). If *exc* is ``NULL``, then the
exception is cleared and the value is clipped to ``PY_SSIZE_T_MIN`` for a negative
@@ -285,6 +286,6 @@ Number Protocol
.. c:function:: int PyIndex_Check(PyObject *o)
- Returns ``1`` if *o* is an index integer (has the nb_index slot of the
- tp_as_number structure filled in), and ``0`` otherwise.
+ Returns ``1`` if *o* is an index integer (has the ``nb_index`` slot of the
+ ``tp_as_number`` structure filled in), and ``0`` otherwise.
This function always succeeds.
diff --git a/Doc/c-api/objbuffer.rst b/Doc/c-api/objbuffer.rst
new file mode 100644
index 00000000000000..6b82a642d7ee42
--- /dev/null
+++ b/Doc/c-api/objbuffer.rst
@@ -0,0 +1,55 @@
+.. highlight:: c
+
+Old Buffer Protocol
+-------------------
+
+.. deprecated:: 3.0
+
+These functions were part of the "old buffer protocol" API in Python 2.
+In Python 3, this protocol doesn't exist anymore but the functions are still
+exposed to ease porting 2.x code. They act as a compatibility wrapper
+around the :ref:`new buffer protocol `, but they don't give
+you control over the lifetime of the resources acquired when a buffer is
+exported.
+
+Therefore, it is recommended that you call :c:func:`PyObject_GetBuffer`
+(or the ``y*`` or ``w*`` :ref:`format codes ` with the
+:c:func:`PyArg_ParseTuple` family of functions) to get a buffer view over
+an object, and :c:func:`PyBuffer_Release` when the buffer view can be released.
+
+
+.. c:function:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)
+
+ Returns a pointer to a read-only memory location usable as character-based
+ input. The *obj* argument must support the single-segment character buffer
+ interface. On success, returns ``0``, sets *buffer* to the memory location
+ and *buffer_len* to the buffer length. Returns ``-1`` and sets a
+ :exc:`TypeError` on error.
+
+
+.. c:function:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
+
+ Returns a pointer to a read-only memory location containing arbitrary data.
+ The *obj* argument must support the single-segment readable buffer
+ interface. On success, returns ``0``, sets *buffer* to the memory location
+ and *buffer_len* to the buffer length. Returns ``-1`` and sets a
+ :exc:`TypeError` on error.
+
+
+.. c:function:: int PyObject_CheckReadBuffer(PyObject *o)
+
+ Returns ``1`` if *o* supports the single-segment readable buffer interface.
+ Otherwise returns ``0``. This function always succeeds.
+
+ Note that this function tries to get and release a buffer, and exceptions
+ which occur while calling corresponding functions will get suppressed.
+ To get error reporting use :c:func:`PyObject_GetBuffer()` instead.
+
+
+.. c:function:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
+
+ Returns a pointer to a writable memory location. The *obj* argument must
+ support the single-segment, character buffer interface. On success,
+ returns ``0``, sets *buffer* to the memory location and *buffer_len* to the
+ buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error.
+
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index 42e3340acb79a0..07a625bac02fc4 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -81,8 +81,9 @@ Object Protocol
return ``0`` on success. This is the equivalent of the Python statement
``o.attr_name = v``.
- If *v* is ``NULL``, the attribute is deleted, however this feature is
- deprecated in favour of using :c:func:`PyObject_DelAttr`.
+ If *v* is ``NULL``, the attribute is deleted. This behaviour is deprecated
+ in favour of using :c:func:`PyObject_DelAttr`, but there are currently no
+ plans to remove it.
.. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
@@ -92,7 +93,7 @@ Object Protocol
return ``0`` on success. This is the equivalent of the Python statement
``o.attr_name = v``.
- If *v* is ``NULL``, the attribute is deleted, however this feature is
+ If *v* is ``NULL``, the attribute is deleted, but this feature is
deprecated in favour of using :c:func:`PyObject_DelAttrString`.
@@ -257,7 +258,7 @@ Object Protocol
.. versionchanged:: 3.2
The return type is now Py_hash_t. This is a signed integer the same size
- as Py_ssize_t.
+ as :c:type:`Py_ssize_t`.
.. c:function:: Py_hash_t PyObject_HashNotImplemented(PyObject *o)
@@ -290,7 +291,7 @@ Object Protocol
of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``. This
is equivalent to the Python expression ``type(o)``. This function increments the
reference count of the return value. There's really no reason to use this
- function instead of the common expression ``o->ob_type``, which returns a
+ function instead of the :c:func:`Py_TYPE()` function, which returns a
pointer of type :c:type:`PyTypeObject*`, except when the incremented reference
count is needed.
@@ -311,12 +312,12 @@ Object Protocol
returned. This is the equivalent to the Python expression ``len(o)``.
-.. c:function:: Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t default)
+.. c:function:: Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
Return an estimated length for the object *o*. First try to return its
actual length, then an estimate using :meth:`~object.__length_hint__`, and
finally return the default value. On error return ``-1``. This is the
- equivalent to the Python expression ``operator.length_hint(o, default)``.
+ equivalent to the Python expression ``operator.length_hint(o, defaultvalue)``.
.. versionadded:: 3.4
@@ -358,7 +359,7 @@ Object Protocol
iterated.
-.. c:function:: PyObject* PyObject_GetAiter(PyObject *o)
+.. c:function:: PyObject* PyObject_GetAIter(PyObject *o)
This is the equivalent to the Python expression ``aiter(o)``. Takes an
:class:`AsyncIterable` object and returns an :class:`AsyncIterator` for it.
diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst
index 391907c8c2976a..738bd77e9ce42f 100644
--- a/Doc/c-api/refcounting.rst
+++ b/Doc/c-api/refcounting.rst
@@ -109,11 +109,17 @@ objects.
It is a good idea to use this macro whenever decrementing the reference
count of an object that might be traversed during garbage collection.
+.. c:function:: void Py_IncRef(PyObject *o)
+
+ Increment the reference count for object *o*. A function version of :c:func:`Py_XINCREF`.
+ It can be used for runtime dynamic embedding of Python.
+
+
+.. c:function:: void Py_DecRef(PyObject *o)
+
+ Decrement the reference count for object *o*. A function version of :c:func:`Py_XDECREF`.
+ It can be used for runtime dynamic embedding of Python.
-The following functions are for runtime dynamic embedding of Python:
-``Py_IncRef(PyObject *o)``, ``Py_DecRef(PyObject *o)``. They are
-simply exported function versions of :c:func:`Py_XINCREF` and
-:c:func:`Py_XDECREF`, respectively.
The following functions or macros are only for use within the interpreter core:
:c:func:`_Py_Dealloc`, :c:func:`_Py_ForgetReference`, :c:func:`_Py_NewReference`,
diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst
index 64ce4d1d0c34df..fe7741a2d7a9fb 100644
--- a/Doc/c-api/reflection.rst
+++ b/Doc/c-api/reflection.rst
@@ -31,7 +31,7 @@ Reflection
See also :c:func:`PyThreadState_GetFrame`.
-.. c:function:: int PyFrame_GetBack(PyFrameObject *frame)
+.. c:function:: PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
Get the *frame* next outer frame.
@@ -42,7 +42,7 @@ Reflection
.. versionadded:: 3.9
-.. c:function:: int PyFrame_GetCode(PyFrameObject *frame)
+.. c:function:: PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
Get the *frame* code.
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index 65818859041179..c78d273f9f149f 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -8,10 +8,10 @@ Sequence Protocol
.. c:function:: int PySequence_Check(PyObject *o)
- Return ``1`` if the object provides sequence protocol, and ``0`` otherwise.
+ Return ``1`` if the object provides the sequence protocol, and ``0`` otherwise.
Note that it returns ``1`` for Python classes with a :meth:`__getitem__`
- method unless they are :class:`dict` subclasses since in general case it
- is impossible to determine what the type of keys it supports. This
+ method, unless they are :class:`dict` subclasses, since in general it
+ is impossible to determine what type of keys the class supports. This
function always succeeds.
@@ -69,7 +69,7 @@ Sequence Protocol
is the equivalent of the Python statement ``o[i] = v``. This function *does
not* steal a reference to *v*.
- If *v* is ``NULL``, the element is deleted, however this feature is
+ If *v* is ``NULL``, the element is deleted, but this feature is
deprecated in favour of using :c:func:`PySequence_DelItem`.
@@ -147,7 +147,7 @@ Sequence Protocol
Returns the length of *o*, assuming that *o* was returned by
:c:func:`PySequence_Fast` and that *o* is not ``NULL``. The size can also be
- gotten by calling :c:func:`PySequence_Size` on *o*, but
+ retrieved by calling :c:func:`PySequence_Size` on *o*, but
:c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a
list or tuple.
diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst
index eca19c4d816474..f0d905bae8ae44 100644
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -13,7 +13,7 @@ Set Objects
object: frozenset
This section details the public API for :class:`set` and :class:`frozenset`
-objects. Any functionality not listed below is best accessed using the either
+objects. Any functionality not listed below is best accessed using either
the abstract object protocol (including :c:func:`PyObject_CallMethod`,
:c:func:`PyObject_RichCompareBool`, :c:func:`PyObject_Hash`,
:c:func:`PyObject_Repr`, :c:func:`PyObject_IsTrue`, :c:func:`PyObject_Print`, and
@@ -31,7 +31,7 @@ the abstract object protocol (including :c:func:`PyObject_CallMethod`,
in that it is a fixed size for small sets (much like tuple storage) and will
point to a separate, variable sized block of memory for medium and large sized
sets (much like list storage). None of the fields of this structure should be
- considered public and are subject to change. All access should be done through
+ considered public and all are subject to change. All access should be done through
the documented API rather than by manipulating the values in the structure.
@@ -131,7 +131,7 @@ or :class:`frozenset` or instances of their subtypes.
.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
Add *key* to a :class:`set` instance. Also works with :class:`frozenset`
- instances (like :c:func:`PyTuple_SetItem` it can be used to fill-in the values
+ instances (like :c:func:`PyTuple_SetItem` it can be used to fill in the values
of brand new frozensets before they are exposed to other code). Return ``0`` on
success or ``-1`` on failure. Raise a :exc:`TypeError` if the *key* is
unhashable. Raise a :exc:`MemoryError` if there is no room to grow. Raise a
diff --git a/Doc/c-api/stable.rst b/Doc/c-api/stable.rst
index 9c05cb3c82dfbe..4ae20e93e36785 100644
--- a/Doc/c-api/stable.rst
+++ b/Doc/c-api/stable.rst
@@ -2,37 +2,157 @@
.. _stable:
-***********************************
+***************
+C API Stability
+***************
+
+Python's C API is covered by the Backwards Compatibility Policy, :pep:`387`.
+While the C API will change with every minor release (e.g. from 3.9 to 3.10),
+most changes will be source-compatible, typically by only adding new API.
+Changing existing API or removing API is only done after a deprecation period
+or to fix serious issues.
+
+CPython's Application Binary Interface (ABI) is forward- and
+backwards-compatible across a minor release (if these are compiled the same
+way; see :ref:`stable-abi-platform` below).
+So, code compiled for Python 3.10.0 will work on 3.10.8 and vice versa,
+but will need to be compiled separately for 3.9.x and 3.10.x.
+
+Names prefixed by an underscore, such as ``_Py_InternalState``,
+are private API that can change without notice even in patch releases.
+
+
Stable Application Binary Interface
-***********************************
-
-Traditionally, the C API of Python will change with every release. Most changes
-will be source-compatible, typically by only adding API, rather than changing
-existing API or removing API (although some interfaces do get removed after
-being deprecated first).
-
-Unfortunately, the API compatibility does not extend to binary compatibility
-(the ABI). The reason is primarily the evolution of struct definitions, where
-addition of a new field, or changing the type of a field, might not break the
-API, but can break the ABI. As a consequence, extension modules need to be
-recompiled for every Python release (although an exception is possible on Unix
-when none of the affected interfaces are used). In addition, on Windows,
-extension modules link with a specific pythonXY.dll and need to be recompiled to
-link with a newer one.
-
-Since Python 3.2, a subset of the API has been declared to guarantee a stable
-ABI. Extension modules wishing to use this API (called "limited API") need to
-define ``Py_LIMITED_API``. A number of interpreter details then become hidden
-from the extension module; in return, a module is built that works on any 3.x
-version (x>=2) without recompilation.
-
-In some cases, the stable ABI needs to be extended with new functions.
-Extension modules wishing to use these new APIs need to set ``Py_LIMITED_API``
-to the ``PY_VERSION_HEX`` value (see :ref:`apiabiversion`) of the minimum Python
-version they want to support (e.g. ``0x03030000`` for Python 3.3). Such modules
-will work on all subsequent Python releases, but fail to load (because of
-missing symbols) on the older releases.
-
-As of Python 3.2, the set of functions available to the limited API is
-documented in :pep:`384`. In the C API documentation, API elements that are not
-part of the limited API are marked as "Not part of the limited 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 work with multiple versions of Python.
+Contents of the Limited API are :ref:`listed below `.
+
+To enable this, Python provides a *Stable ABI*: a set of symbols that will
+remain compatible across Python 3.x versions. The Stable ABI contains symbols
+exposed in the Limited API, but also other ones – for example, functions
+necessary to support older versions of the Limited API.
+
+(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.)
+
+.. 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:data:`PY_VERSION_HEX`
+ corresponding to the lowest Python version your extension supports.
+ The extension will work without recompilation 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).
+
+On Windows, extensions that use the Stable ABI should be linked against
+``python3.dll`` rather than a version-specific library such as
+``python39.dll``.
+
+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
+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.
+
+
+Limited API Scope and Performance
+---------------------------------
+
+The goal for the Limited API is to allow everything that is possible with the
+full C API, but possibly with a performance penalty.
+
+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
+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.
+
+
+Limited API Caveats
+-------------------
+
+Note that compiling with ``Py_LIMITED_API`` is *not* a complete guarantee that
+code conforms to the Limited API or the Stable ABI. ``Py_LIMITED_API`` only
+covers definitions, but an API also includes other issues, such as expected
+semantics.
+
+One issue that ``Py_LIMITED_API`` does 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.
+
+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.
+
+
+.. _stable-abi-platform:
+
+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 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.
+This is the case with Windows and macOS releases from ``python.org`` and many
+third-party distributors.
+
+
+.. _stable-abi-list:
+
+Contents of Limited API
+=======================
+
+
+Currently, the Limited API includes the following items:
+
+.. limited-api-list::
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index 20d5485d5544c2..c1c83b035c8515 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -309,8 +309,6 @@ There are these calling conventions:
or possibly ``NULL`` if there are no keywords. The values of the keyword
arguments are stored in the *args* array, after the positional arguments.
- This is not part of the :ref:`limited API `.
-
.. versionadded:: 3.7
@@ -469,6 +467,21 @@ Accessing attributes of extension types
{NULL} /* Sentinel */
};
+
+.. c:function:: PyObject* PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m)
+
+ Get an attribute belonging to the object at address *obj_addr*. The
+ attribute is described by ``PyMemberDef`` *m*. Returns ``NULL``
+ on error.
+
+
+.. c:function:: int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o)
+
+ Set an attribute belonging to the object at address *obj_addr* to object *o*.
+ The attribute to set is described by ``PyMemberDef`` *m*. Returns ``0``
+ if successful and a negative value on failure.
+
+
.. c:type:: PyGetSetDef
Structure to define property-like access for a type. See also description of
@@ -479,7 +492,7 @@ Accessing attributes of extension types
+=============+==================+===================================+
| name | const char \* | attribute name |
+-------------+------------------+-----------------------------------+
- | get | getter | C Function to get the attribute |
+ | get | getter | C function to get the attribute |
+-------------+------------------+-----------------------------------+
| set | setter | optional C function to set or |
| | | delete the attribute, if omitted |
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index 97717f5fc19230..7cf0a6b51f7ddc 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -177,7 +177,7 @@ Operating System Utilities
Return a pointer to a newly allocated byte string, use :c:func:`PyMem_Free`
to free the memory. Return ``NULL`` on encoding error or memory allocation
- error
+ error.
If error_pos is not ``NULL``, ``*error_pos`` is set to ``(size_t)-1`` on
success, or set to the index of the invalid character on encoding error.
@@ -207,7 +207,7 @@ Operating System Utilities
.. versionchanged:: 3.8
The function now uses the UTF-8 encoding on Windows if
- :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero;
+ :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero.
.. _systemfunctions:
@@ -323,7 +323,7 @@ accessible to C code. They all work with the current interpreter thread's
leaks.)
Note that ``#`` format characters should always be treated as
- ``Py_ssize_t``, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined.
+ :c:type:`Py_ssize_t`, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined.
:func:`sys.audit` performs the same function from Python code.
@@ -331,14 +331,14 @@ accessible to C code. They all work with the current interpreter thread's
.. versionchanged:: 3.8.2
- Require ``Py_ssize_t`` for ``#`` format characters. Previously, an
+ Require :c:type:`Py_ssize_t` for ``#`` format characters. Previously, an
unavoidable deprecation warning was raised.
.. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
Append the callable *hook* to the list of active auditing hooks.
- Return zero for success
+ Return zero on success
and non-zero on failure. If the runtime has been initialized, also set an
error on failure. Hooks added through this API are called for all
interpreters created by the runtime.
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index bdb636dff326f2..01d00bede544d7 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -13,7 +13,7 @@ Type Objects
The C structure of the objects used to describe built-in types.
-.. c:var:: PyObject* PyType_Type
+.. c:var:: PyTypeObject PyType_Type
This is the type object for type objects; it is the same object as
:class:`type` in the Python layer.
@@ -97,6 +97,15 @@ Type Objects
from a type's base class. Return ``0`` on success, or return ``-1`` and sets an
exception on error.
+ .. note::
+ If some of the base classes implements the GC protocol and the provided
+ type does not include the :const:`Py_TPFLAGS_HAVE_GC` in its flags, then
+ the GC protocol will be automatically implemented from its parents. On
+ the contrary, if the type being created does include
+ :const:`Py_TPFLAGS_HAVE_GC` in its flags then it **must** implement the
+ GC protocol itself by at least implementing the
+ :c:member:`~PyTypeObject.tp_traverse` handle.
+
.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot)
Return the function pointer stored in the given slot. If the
@@ -165,7 +174,7 @@ The following functions and structs are used to create
The *module* argument can be used to record the module in which the new
class is defined. It must be a module object or ``NULL``.
If not ``NULL``, the module is associated with the new type and can later be
- retreived with :c:func:`PyType_GetModule`.
+ retrieved with :c:func:`PyType_GetModule`.
The associated module is not inherited by subclasses; it must be specified
for each class individually.
@@ -263,7 +272,7 @@ The following functions and structs are used to create
.. versionchanged:: 3.9
- Slots in :c:type:`PyBufferProcs` in may be set in the unlimited API.
+ Slots in :c:type:`PyBufferProcs` may be set in the unlimited API.
.. c:member:: void *PyType_Slot.pfunc
diff --git a/Doc/c-api/typehints.rst b/Doc/c-api/typehints.rst
new file mode 100644
index 00000000000000..dfda96a47243bd
--- /dev/null
+++ b/Doc/c-api/typehints.rst
@@ -0,0 +1,47 @@
+.. highlight:: c
+
+.. _typehintobjects:
+
+Objects for Type Hinting
+------------------------
+
+Various built-in types for type hinting are provided. Currently,
+two types exist -- :ref:`GenericAlias ` and
+:ref:`Union `. Only ``GenericAlias`` is exposed to C.
+
+.. c:function:: PyObject* Py_GenericAlias(PyObject *origin, PyObject *args)
+
+ Create a :ref:`GenericAlias ` object.
+ Equivalent to calling the Python class
+ :class:`types.GenericAlias`. The *origin* and *args* arguments set the
+ ``GenericAlias``\ 's ``__origin__`` and ``__args__`` attributes respectively.
+ *origin* should be a :c:type:`PyTypeObject*`, and *args* can be a
+ :c:type:`PyTupleObject*` or any ``PyObject*``. If *args* passed is
+ not a tuple, a 1-tuple is automatically constructed and ``__args__`` is set
+ to ``(args,)``.
+ Minimal checking is done for the arguments, so the function will succeed even
+ if *origin* is not a type.
+ The ``GenericAlias``\ 's ``__parameters__`` attribute is constructed lazily
+ from ``__args__``. On failure, an exception is raised and ``NULL`` is
+ returned.
+
+ Here's an example of how to make an extension type generic::
+
+ ...
+ static PyMethodDef my_obj_methods[] = {
+ // Other methods.
+ ...
+ {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, "See PEP 585"}
+ ...
+ }
+
+ .. seealso:: The data model method :meth:`__class_getitem__`.
+
+ .. versionadded:: 3.9
+
+.. c:var:: PyTypeObject Py_GenericAliasType
+
+ The C type of the object returned by :c:func:`Py_GenericAlias`. Equivalent to
+ :class:`types.GenericAlias` in Python.
+
+ .. versionadded:: 3.9
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 82f2ab53451166..3da1403be29fa7 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -43,13 +43,13 @@ Quick Reference
+================================================+===================================+===================+===+===+===+===+
| :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
- | :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X |
+ | :c:member:`~PyTypeObject.tp_basicsize` | :c:type:`Py_ssize_t` | | X | X | | X |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
- | :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X |
+ | :c:member:`~PyTypeObject.tp_itemsize` | :c:type:`Py_ssize_t` | | | X | | X |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
| :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
- | :c:member:`~PyTypeObject.tp_vectorcall_offset` | Py_ssize_t | | | X | | X |
+ | :c:member:`~PyTypeObject.tp_vectorcall_offset` | :c:type:`Py_ssize_t` | | | X | | X |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
| (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G |
| | | __getattr__ | | | | |
@@ -96,7 +96,7 @@ Quick Reference
| | | __gt__, | | | | |
| | | __ge__ | | | | |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
- | :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? |
+ | :c:member:`~PyTypeObject.tp_weaklistoffset` | :c:type:`Py_ssize_t` | | | X | | ? |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
| :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
@@ -117,7 +117,7 @@ Quick Reference
| :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X |
| | | __delete__ | | | | |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
- | :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? |
+ | :c:member:`~PyTypeObject.tp_dictoffset` | :c:type:`Py_ssize_t` | | | X | | ? |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
| :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
@@ -189,138 +189,138 @@ sub-slots
.. table::
:widths: 26,17,12
- +---------------------------------------------------------+-----------------------------------+--------------+
- | Slot | :ref:`Type ` | special |
- | | | methods |
- +=========================================================+===================================+==============+
- | :c:member:`~PyAsyncMethods.am_await` | :c:type:`unaryfunc` | __await__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyAsyncMethods.am_aiter` | :c:type:`unaryfunc` | __aiter__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyAsyncMethods.am_anext` | :c:type:`unaryfunc` | __anext__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyAsyncMethods.am_send` | :c:type:`sendfunc` | |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_add` | :c:type:`binaryfunc` | __add__ |
- | | | __radd__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_add` | :c:type:`binaryfunc` | __iadd__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_subtract` | :c:type:`binaryfunc` | __sub__ |
- | | | __rsub__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_subtract` | :c:type:`binaryfunc` | __sub__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_multiply` | :c:type:`binaryfunc` | __mul__ |
- | | | __rmul__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_multiply` | :c:type:`binaryfunc` | __mul__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_remainder` | :c:type:`binaryfunc` | __mod__ |
- | | | __rmod__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_remainder` | :c:type:`binaryfunc` | __mod__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_divmod` | :c:type:`binaryfunc` | __divmod__ |
- | | | __rdivmod__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_power` | :c:type:`ternaryfunc` | __pow__ |
- | | | __rpow__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_power` | :c:type:`ternaryfunc` | __pow__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_negative` | :c:type:`unaryfunc` | __neg__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_positive` | :c:type:`unaryfunc` | __pos__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_absolute` | :c:type:`unaryfunc` | __abs__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_bool` | :c:type:`inquiry` | __bool__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_invert` | :c:type:`unaryfunc` | __invert__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_lshift` | :c:type:`binaryfunc` | __lshift__ |
- | | | __rlshift__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_lshift` | :c:type:`binaryfunc` | __lshift__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_rshift` | :c:type:`binaryfunc` | __rshift__ |
- | | | __rrshift__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_rshift` | :c:type:`binaryfunc` | __rshift__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_and` | :c:type:`binaryfunc` | __and__ |
- | | | __rand__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_and` | :c:type:`binaryfunc` | __and__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_xor` | :c:type:`binaryfunc` | __xor__ |
- | | | __rxor__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_xor` | :c:type:`binaryfunc` | __xor__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_or` | :c:type:`binaryfunc` | __or__ |
- | | | __ror__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_or` | :c:type:`binaryfunc` | __or__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_int` | :c:type:`unaryfunc` | __int__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_reserved` | void * | |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_float` | :c:type:`unaryfunc` | __float__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_floor_divide` | :c:type:`binaryfunc` | __floordiv__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_floor_divide` | :c:type:`binaryfunc` | __floordiv__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_true_divide` | :c:type:`binaryfunc` | __truediv__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_true_divide` | :c:type:`binaryfunc` | __truediv__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_index` | :c:type:`unaryfunc` | __index__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ |
- | | | __rmatmul__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyNumberMethods.nb_inplace_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyMappingMethods.mp_length` | :c:type:`lenfunc` | __len__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyMappingMethods.mp_subscript` | :c:type:`binaryfunc` | __getitem__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyMappingMethods.mp_ass_subscript` | :c:type:`objobjargproc` | __setitem__, |
- | | | __delitem__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_length` | :c:type:`lenfunc` | __len__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_concat` | :c:type:`binaryfunc` | __add__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_repeat` | :c:type:`ssizeargfunc` | __mul__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_item` | :c:type:`ssizeargfunc` | __getitem__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_ass_item` | :c:type:`ssizeobjargproc` | __setitem__ |
- | | | __delitem__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_contains` | :c:type:`objobjproc` | __contains__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_inplace_concat` | :c:type:`binaryfunc` | __iadd__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PySequenceMethods.sq_inplace_repeat` | :c:type:`ssizeargfunc` | __imul__ |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyBufferProcs.bf_getbuffer` | :c:func:`getbufferproc` | |
- +---------------------------------------------------------+-----------------------------------+--------------+
- | :c:member:`~PyBufferProcs.bf_releasebuffer` | :c:func:`releasebufferproc` | |
- +---------------------------------------------------------+-----------------------------------+--------------+
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | Slot | :ref:`Type ` | special |
+ | | | methods |
+ +=========================================================+===================================+===============+
+ | :c:member:`~PyAsyncMethods.am_await` | :c:type:`unaryfunc` | __await__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyAsyncMethods.am_aiter` | :c:type:`unaryfunc` | __aiter__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyAsyncMethods.am_anext` | :c:type:`unaryfunc` | __anext__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyAsyncMethods.am_send` | :c:type:`sendfunc` | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_add` | :c:type:`binaryfunc` | __add__ |
+ | | | __radd__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_add` | :c:type:`binaryfunc` | __iadd__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_subtract` | :c:type:`binaryfunc` | __sub__ |
+ | | | __rsub__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_subtract` | :c:type:`binaryfunc` | __isub__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_multiply` | :c:type:`binaryfunc` | __mul__ |
+ | | | __rmul__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_multiply` | :c:type:`binaryfunc` | __imul__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_remainder` | :c:type:`binaryfunc` | __mod__ |
+ | | | __rmod__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_remainder` | :c:type:`binaryfunc` | __imod__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_divmod` | :c:type:`binaryfunc` | __divmod__ |
+ | | | __rdivmod__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_power` | :c:type:`ternaryfunc` | __pow__ |
+ | | | __rpow__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_power` | :c:type:`ternaryfunc` | __ipow__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_negative` | :c:type:`unaryfunc` | __neg__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_positive` | :c:type:`unaryfunc` | __pos__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_absolute` | :c:type:`unaryfunc` | __abs__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_bool` | :c:type:`inquiry` | __bool__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_invert` | :c:type:`unaryfunc` | __invert__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_lshift` | :c:type:`binaryfunc` | __lshift__ |
+ | | | __rlshift__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_lshift` | :c:type:`binaryfunc` | __ilshift__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_rshift` | :c:type:`binaryfunc` | __rshift__ |
+ | | | __rrshift__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_rshift` | :c:type:`binaryfunc` | __irshift__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_and` | :c:type:`binaryfunc` | __and__ |
+ | | | __rand__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_and` | :c:type:`binaryfunc` | __iand__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_xor` | :c:type:`binaryfunc` | __xor__ |
+ | | | __rxor__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_xor` | :c:type:`binaryfunc` | __ixor__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_or` | :c:type:`binaryfunc` | __or__ |
+ | | | __ror__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_or` | :c:type:`binaryfunc` | __ior__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_int` | :c:type:`unaryfunc` | __int__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_reserved` | void * | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_float` | :c:type:`unaryfunc` | __float__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_floor_divide` | :c:type:`binaryfunc` | __floordiv__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_floor_divide` | :c:type:`binaryfunc` | __ifloordiv__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_true_divide` | :c:type:`binaryfunc` | __truediv__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_true_divide` | :c:type:`binaryfunc` | __itruediv__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_index` | :c:type:`unaryfunc` | __index__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ |
+ | | | __rmatmul__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyNumberMethods.nb_inplace_matrix_multiply` | :c:type:`binaryfunc` | __imatmul__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyMappingMethods.mp_length` | :c:type:`lenfunc` | __len__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyMappingMethods.mp_subscript` | :c:type:`binaryfunc` | __getitem__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyMappingMethods.mp_ass_subscript` | :c:type:`objobjargproc` | __setitem__, |
+ | | | __delitem__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_length` | :c:type:`lenfunc` | __len__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_concat` | :c:type:`binaryfunc` | __add__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_repeat` | :c:type:`ssizeargfunc` | __mul__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_item` | :c:type:`ssizeargfunc` | __getitem__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_ass_item` | :c:type:`ssizeobjargproc` | __setitem__ |
+ | | | __delitem__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_contains` | :c:type:`objobjproc` | __contains__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_inplace_concat` | :c:type:`binaryfunc` | __iadd__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PySequenceMethods.sq_inplace_repeat` | :c:type:`ssizeargfunc` | __imul__ |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyBufferProcs.bf_getbuffer` | :c:func:`getbufferproc` | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
+ | :c:member:`~PyBufferProcs.bf_releasebuffer` | :c:func:`releasebufferproc` | |
+ +---------------------------------------------------------+-----------------------------------+---------------+
.. _slot-typedefs-table:
@@ -333,7 +333,7 @@ slot typedefs
| :c:type:`allocfunc` | .. line-block:: | :c:type:`PyObject` * |
| | | |
| | :c:type:`PyTypeObject` * | |
-| | Py_ssize_t | |
+| | :c:type:`Py_ssize_t` | |
+-----------------------------+-----------------------------+----------------------+
| :c:type:`destructor` | void * | void |
+-----------------------------+-----------------------------+----------------------+
@@ -405,7 +405,7 @@ slot typedefs
+-----------------------------+-----------------------------+----------------------+
| :c:type:`iternextfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * |
+-----------------------------+-----------------------------+----------------------+
-| :c:type:`lenfunc` | :c:type:`PyObject` * | Py_ssize_t |
+| :c:type:`lenfunc` | :c:type:`PyObject` * | :c:type:`Py_ssize_t` |
+-----------------------------+-----------------------------+----------------------+
| :c:type:`getbufferproc` | .. line-block:: | int |
| | | |
@@ -438,12 +438,12 @@ slot typedefs
| :c:type:`ssizeargfunc` | .. line-block:: | :c:type:`PyObject` * |
| | | |
| | :c:type:`PyObject` * | |
-| | Py_ssize_t | |
+| | :c:type:`Py_ssize_t` | |
+-----------------------------+-----------------------------+----------------------+
| :c:type:`ssizeobjargproc` | .. line-block:: | int |
| | | |
| | :c:type:`PyObject` * | |
-| | Py_ssize_t | |
+| | :c:type:`Py_ssize_t` | |
+-----------------------------+-----------------------------+----------------------+
| :c:type:`objobjproc` | .. line-block:: | int |
| | | |
@@ -476,7 +476,7 @@ PyObject Slots
--------------
The type object structure extends the :c:type:`PyVarObject` structure. The
-:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`,
+:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`,
usually called from a class statement). Note that :c:data:`PyType_Type` (the
metatype) initializes :c:member:`~PyTypeObject.tp_itemsize`, which means that its instances (i.e.
type objects) *must* have the :attr:`ob_size` field.
@@ -668,6 +668,18 @@ and :c:type:`PyType_Type` effectively act as defaults.)
:c:func:`PyObject_GC_Del` if the instance was allocated using
:c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`.
+ If the type supports garbage collection (has the :const:`Py_TPFLAGS_HAVE_GC`
+ flag bit set), the destructor should call :c:func:`PyObject_GC_UnTrack`
+ before clearing any member fields.
+
+ .. code-block:: c
+
+ static void foo_dealloc(foo_object *self) {
+ PyObject_GC_UnTrack(self);
+ Py_CLEAR(self->ref);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+ }
+
Finally, if the type is heap allocated (:const:`Py_TPFLAGS_HEAPTYPE`), the
deallocator should decrement the reference count for its type object after
calling the type deallocator. In order to avoid dangling pointers, the
@@ -715,12 +727,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
When a user sets :attr:`__call__` in Python code, only *tp_call* is updated,
likely making it inconsistent with the vectorcall function.
- .. note::
-
- The semantics of the ``tp_vectorcall_offset`` slot are provisional and
- expected to be finalized in Python 3.9.
- If you use vectorcall, plan for updating your code for Python 3.9.
-
.. versionchanged:: 3.8
Before version 3.8, this slot was named ``tp_print``.
@@ -1097,8 +1103,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
This is a bitmask of all the bits that pertain to the existence of certain
fields in the type object and its extension structures. Currently, it includes
- the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`,
- :const:`Py_TPFLAGS_HAVE_VERSION_TAG`.
+ the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`.
**Inheritance:**
@@ -1178,14 +1183,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. versionadded:: 3.9
-
- .. data:: Py_TPFLAGS_HAVE_AM_SEND
-
- This bit is set when the :c:member:`~PyAsyncMethods.am_send` entry is present in the
- :c:member:`~PyTypeObject.tp_as_async` slot of type structure.
-
- .. versionadded:: 3.10
-
.. data:: Py_TPFLAGS_IMMUTABLETYPE
This bit is set for type objects that are immutable: type attributes cannot be set nor deleted.
@@ -1229,7 +1226,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. note::
:const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are
- mutually exclusive; it is an error enable both flags simultaneously.
+ mutually exclusive; it is an error to enable both flags simultaneously.
**Inheritance:**
@@ -1251,7 +1248,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. note::
:const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are
- mutually exclusive; it is an error enable both flags simultaneously.
+ mutually exclusive; it is an error to enable both flags simultaneously.
**Inheritance:**
@@ -1389,6 +1386,12 @@ and :c:type:`PyType_Type` effectively act as defaults.)
so that *self* knows the contained object can no longer be used. The
:c:func:`Py_CLEAR` macro performs the operations in a safe order.
+ Note that :c:member:`~PyTypeObject.tp_clear` is not *always* called
+ before an instance is deallocated. For example, when reference counting
+ is enough to determine that an object is no longer used, the cyclic garbage
+ collector is not involved and :c:member:`~PyTypeObject.tp_dealloc` is
+ called directly.
+
Because the goal of :c:member:`~PyTypeObject.tp_clear` functions is to break reference cycles,
it's not necessary to clear contained objects like Python strings or Python
integers, which can't participate in reference cycles. On the other hand, it may
@@ -1511,9 +1514,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. c:member:: getiterfunc PyTypeObject.tp_iter
- An optional pointer to a function that returns an iterator for the object. Its
- presence normally signals that the instances of this type are iterable (although
- sequences may be iterable without this function).
+ An optional pointer to a function that returns an :term:`iterator` for the
+ object. Its presence normally signals that the instances of this type are
+ :term:`iterable` (although sequences may be iterable without this function).
This function has the same signature as :c:func:`PyObject_GetIter`::
@@ -1526,8 +1529,8 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. c:member:: iternextfunc PyTypeObject.tp_iternext
- An optional pointer to a function that returns the next item in an iterator.
- The signature is::
+ An optional pointer to a function that returns the next item in an
+ :term:`iterator`. The signature is::
PyObject *tp_iternext(PyObject *self);
@@ -1990,6 +1993,17 @@ and :c:type:`PyType_Type` effectively act as defaults.)
For this field to be taken into account (even through inheritance),
you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit.
+ Also, note that, in a garbage collected Python,
+ :c:member:`~PyTypeObject.tp_dealloc` may be called from
+ any Python thread, not just the thread which created the object (if the object
+ becomes part of a refcount cycle, that cycle might be collected by a garbage
+ collection on any thread). This is not a problem for Python API calls, since
+ the thread on which tp_dealloc is called will own the Global Interpreter Lock
+ (GIL). However, if the object being destroyed in turn destroys objects from some
+ other C or C++ library, care should be taken to ensure that destroying those
+ objects on the thread which called tp_dealloc will not violate any assumptions
+ of the library.
+
**Inheritance:**
This field is inherited by subtypes.
@@ -2014,17 +2028,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9)
-Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from
-any Python thread, not just the thread which created the object (if the object
-becomes part of a refcount cycle, that cycle might be collected by a garbage
-collection on any thread). This is not a problem for Python API calls, since
-the thread on which tp_dealloc is called will own the Global Interpreter Lock
-(GIL). However, if the object being destroyed in turn destroys objects from some
-other C or C++ library, care should be taken to ensure that destroying those
-objects on the thread which called tp_dealloc will not violate any assumptions
-of the library.
-
-
.. _static-types:
Static Types
@@ -2419,8 +2422,8 @@ Async Object Structures
PyObject *am_await(PyObject *self);
- The returned object must be an iterator, i.e. :c:func:`PyIter_Check` must
- return ``1`` for it.
+ The returned object must be an :term:`iterator`, i.e. :c:func:`PyIter_Check`
+ must return ``1`` for it.
This slot may be set to ``NULL`` if an object is not an :term:`awaitable`.
@@ -2430,7 +2433,8 @@ Async Object Structures
PyObject *am_aiter(PyObject *self);
- Must return an :term:`awaitable` object. See :meth:`__anext__` for details.
+ Must return an :term:`asynchronous iterator` object.
+ See :meth:`__anext__` for details.
This slot may be set to ``NULL`` if an object does not implement
asynchronous iteration protocol.
@@ -2453,6 +2457,8 @@ Async Object Structures
See :c:func:`PyIter_Send` for details.
This slot may be set to ``NULL``.
+ .. versionadded:: 3.10
+
.. _slot-typedefs:
@@ -2516,11 +2522,11 @@ Slot Type typedefs
.. c:type:: PyObject *(*descrgetfunc)(PyObject *, PyObject *, PyObject *)
- See :c:member:`~PyTypeObject.tp_descrget`.
+ See :c:member:`~PyTypeObject.tp_descr_get`.
.. c:type:: int (*descrsetfunc)(PyObject *, PyObject *, PyObject *)
- See :c:member:`~PyTypeObject.tp_descrset`.
+ See :c:member:`~PyTypeObject.tp_descr_set`.
.. c:type:: Py_hash_t (*hashfunc)(PyObject *)
@@ -2584,7 +2590,7 @@ A basic :ref:`static type `::
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
- .tp_doc = "My objects",
+ .tp_doc = PyDoc_STR("My objects"),
.tp_new = myobj_new,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
@@ -2614,7 +2620,7 @@ with a more verbose initializer::
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
- "My objects", /* tp_doc */
+ PyDoc_STR("My objects"), /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
@@ -2647,7 +2653,7 @@ A type that supports weakrefs, instance dicts, and hashing::
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
- .tp_doc = "My objects",
+ .tp_doc = PyDoc_STR("My objects"),
.tp_weaklistoffset = offsetof(MyObject, weakreflist),
.tp_dictoffset = offsetof(MyObject, inst_dict),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
@@ -2675,7 +2681,7 @@ to create instances (e.g. uses a separate factory func) using
.tp_name = "mymod.MyStr",
.tp_basicsize = sizeof(MyStr),
.tp_base = NULL, // set to &PyUnicode_Type in module init
- .tp_doc = "my custom str",
+ .tp_doc = PyDoc_STR("my custom str"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
.tp_repr = (reprfunc)myobj_repr,
};
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 8d4eef87db9fb6..09ded4c32db07e 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -149,7 +149,7 @@ access internal read-only data of Unicode objects:
``PyUnicode_WCHAR_KIND`` is deprecated.
-.. c:function:: int PyUnicode_KIND(PyObject *o)
+.. c:function:: unsigned int PyUnicode_KIND(PyObject *o)
Return one of the PyUnicode kind constants (see above) that indicate how many
bytes per character this Unicode object uses to store its data. *o* has to
@@ -268,57 +268,57 @@ are available through these macros which are mapped to C functions depending on
the Python configuration.
-.. c:function:: int Py_UNICODE_ISSPACE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISSPACE(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a whitespace character.
-.. c:function:: int Py_UNICODE_ISLOWER(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISLOWER(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a lowercase character.
-.. c:function:: int Py_UNICODE_ISUPPER(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISUPPER(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is an uppercase character.
-.. c:function:: int Py_UNICODE_ISTITLE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISTITLE(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a titlecase character.
-.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a linebreak character.
-.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a decimal character.
-.. c:function:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISDIGIT(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a digit character.
-.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a numeric character.
-.. c:function:: int Py_UNICODE_ISALPHA(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISALPHA(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is an alphabetic character.
-.. c:function:: int Py_UNICODE_ISALNUM(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISALNUM(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is an alphanumeric character.
-.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UCS4 ch)
Return ``1`` or ``0`` depending on whether *ch* is a printable character.
Nonprintable characters are those characters defined in the Unicode character
@@ -332,7 +332,7 @@ the Python configuration.
These APIs can be used for fast direct character conversions:
-.. c:function:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch)
+.. c:function:: Py_UCS4 Py_UNICODE_TOLOWER(Py_UCS4 ch)
Return the character *ch* converted to lower case.
@@ -340,7 +340,7 @@ These APIs can be used for fast direct character conversions:
This function uses simple case mappings.
-.. c:function:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch)
+.. c:function:: Py_UCS4 Py_UNICODE_TOUPPER(Py_UCS4 ch)
Return the character *ch* converted to upper case.
@@ -348,7 +348,7 @@ These APIs can be used for fast direct character conversions:
This function uses simple case mappings.
-.. c:function:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch)
+.. c:function:: Py_UCS4 Py_UNICODE_TOTITLE(Py_UCS4 ch)
Return the character *ch* converted to title case.
@@ -356,19 +356,19 @@ These APIs can be used for fast direct character conversions:
This function uses simple case mappings.
-.. c:function:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_TODECIMAL(Py_UCS4 ch)
Return the character *ch* converted to a decimal positive integer. Return
``-1`` if this is not possible. This macro does not raise exceptions.
-.. c:function:: int Py_UNICODE_TODIGIT(Py_UNICODE ch)
+.. c:function:: int Py_UNICODE_TODIGIT(Py_UCS4 ch)
Return the character *ch* converted to a single digit integer. Return ``-1`` if
this is not possible. This macro does not raise exceptions.
-.. c:function:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch)
+.. c:function:: double Py_UNICODE_TONUMERIC(Py_UCS4 ch)
Return the character *ch* converted to a double. Return ``-1.0`` if this is not
possible. This macro does not raise exceptions.
@@ -490,11 +490,11 @@ APIs:
| :attr:`%llu` | unsigned long long | Equivalent to |
| | | ``printf("%llu")``. [1]_ |
+-------------------+---------------------+----------------------------------+
- | :attr:`%zd` | Py_ssize_t | Equivalent to |
- | | | ``printf("%zd")``. [1]_ |
+ | :attr:`%zd` | :c:type:`\ | Equivalent to |
+ | | Py_ssize_t` | ``printf("%zd")``. [1]_ |
+-------------------+---------------------+----------------------------------+
- | :attr:`%zi` | Py_ssize_t | Equivalent to |
- | | | ``printf("%zi")``. [1]_ |
+ | :attr:`%zi` | :c:type:`\ | Equivalent to |
+ | | Py_ssize_t` | ``printf("%zi")``. [1]_ |
+-------------------+---------------------+----------------------------------+
| :attr:`%zu` | size_t | Equivalent to |
| | | ``printf("%zu")``. [1]_ |
@@ -1008,7 +1008,7 @@ Error handling is set by errors which may also be set to ``NULL`` meaning to use
the default handling defined for the codec. Default error handling for all
built-in codecs is "strict" (:exc:`ValueError` is raised).
-The codecs all use a similar interface. Only deviation from the following
+The codecs all use a similar interface. Only deviations from the following
generic ones are documented for simplicity.
@@ -1093,7 +1093,8 @@ These are the UTF-8 codec APIs:
This caches the UTF-8 representation of the string in the Unicode object, and
subsequent calls will return a pointer to the same buffer. The caller is not
- responsible for deallocating the buffer.
+ responsible for deallocating the buffer. The buffer is deallocated and
+ pointers to it become invalid when the Unicode object is garbage collected.
.. versionadded:: 3.3
@@ -1225,7 +1226,7 @@ These are the UTF-16 codec APIs:
``1``, any byte order mark is copied to the output (where it will result in
either a ``\ufeff`` or a ``\ufffe`` character).
- After completion, *\*byteorder* is set to the current byte order at the end
+ After completion, ``*byteorder`` is set to the current byte order at the end
of input data.
If *byteorder* is ``NULL``, the codec starts in native order mode.
@@ -1443,7 +1444,7 @@ Character Map Codecs
This codec is special in that it can be used to implement many different codecs
(and this is in fact what was done to obtain most of the standard codecs
-included in the :mod:`encodings` package). The codec uses mapping to encode and
+included in the :mod:`encodings` package). The codec uses mappings to encode and
decode characters. The mapping objects provided must support the
:meth:`__getitem__` mapping interface; dictionaries and sequences work well.
@@ -1605,7 +1606,7 @@ They all return ``NULL`` or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend)
Split a Unicode string at line breaks, returning a list of Unicode strings.
- CRLF is considered to be one line break. If *keepend* is ``0``, the Line break
+ CRLF is considered to be one line break. If *keepend* is ``0``, the line break
characters are not included in the resulting strings.
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 0f760eaa7ad578..5b8735de75e9d0 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -75,6 +75,8 @@ the same library that the Python runtime is using.
:c:func:`PyRun_SimpleFile`. *filename* is decoded from the filesystem
encoding (:func:`sys.getfilesystemencoding`). If *filename* is ``NULL``, this
function uses ``"???"`` as the filename.
+ If *closeit* is true, the file is closed before
+ ``PyRun_SimpleFileExFlags()`` returns.
.. c:function:: int PyRun_SimpleString(const char *command)
@@ -185,42 +187,6 @@ the same library that the Python runtime is using.
:c:func:`PyMem_RawRealloc`, instead of being allocated by
:c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`.
-
-.. c:function:: struct _node* PyParser_SimpleParseString(const char *str, int start)
-
- This is a simplified interface to
- :c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
- to ``NULL`` and *flags* set to ``0``.
-
-
-.. c:function:: struct _node* PyParser_SimpleParseStringFlags( const char *str, int start, int flags)
-
- This is a simplified interface to
- :c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
- to ``NULL``.
-
-
-.. c:function:: struct _node* PyParser_SimpleParseStringFlagsFilename( const char *str, const char *filename, int start, int flags)
-
- Parse Python source code from *str* using the start token *start* according to
- the *flags* argument. The result can be used to create a code object which can
- be evaluated efficiently. This is useful if a code fragment must be evaluated
- many times. *filename* is decoded from the :term:`filesystem encoding and
- error handler`.
-
-
-.. c:function:: struct _node* PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
-
- This is a simplified interface to :c:func:`PyParser_SimpleParseFileFlags` below,
- leaving *flags* set to ``0``.
-
-
-.. c:function:: struct _node* PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
-
- Similar to :c:func:`PyParser_SimpleParseStringFlagsFilename`, but the Python
- source code is read from *fp* instead of an in-memory string.
-
-
.. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
This is a simplified interface to :c:func:`PyRun_StringFlags` below, leaving
diff --git a/Doc/conf.py b/Doc/conf.py
index cf250981f58752..01243de7805ddc 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -45,7 +45,7 @@
highlight_language = 'python3'
# Minimum version of sphinx required
-needs_sphinx = '1.8'
+needs_sphinx = '3.2'
# Ignore any .rst files in the venv/ directory.
exclude_patterns = ['venv/*', 'README.rst']
@@ -69,7 +69,8 @@
html_theme_path = ['tools']
html_theme_options = {
'collapsiblesidebar': True,
- 'issues_url': 'https://docs.python.org/3/bugs.html',
+ 'issues_url': '/bugs.html',
+ 'license_url': '/license.html',
'root_include_title': False # We use the version switcher instead.
}
@@ -85,7 +86,7 @@
# Custom sidebar templates, filenames relative to this file.
html_sidebars = {
- # Defaults taken from http://www.sphinx-doc.org/en/stable/config.html#confval-html_sidebars
+ # Defaults taken from https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_sidebars
# Removes the quick search block
'**': ['localtoc.html', 'relations.html', 'customsourcelink.html'],
'index': ['indexsidebar.html'],
@@ -225,8 +226,9 @@
# Options for extensions
# ----------------------
-# Relative filename of the reference count data file.
+# Relative filename of the data files
refcount_file = 'data/refcounts.dat'
+stable_abi_file = 'data/stable_abi.dat'
# Sphinx 2 and Sphinx 3 compatibility
# -----------------------------------
@@ -237,5 +239,3 @@
# bpo-40204: Disable warnings on Sphinx 2 syntax of the C domain since the
# documentation is built with -W (warnings treated as errors).
c_warn_on_allowed_pre_v3 = False
-
-strip_signature_backslash = True
diff --git a/Doc/copyright.rst b/Doc/copyright.rst
index 4191c0bb63a2c1..e64a49328b4723 100644
--- a/Doc/copyright.rst
+++ b/Doc/copyright.rst
@@ -4,7 +4,7 @@ Copyright
Python and this documentation is:
-Copyright © 2001-2021 Python Software Foundation. All rights reserved.
+Copyright © 2001-2022 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
diff --git a/Doc/data/python3.10.abi b/Doc/data/python3.10.abi
new file mode 100644
index 00000000000000..b7886ae28f7007
--- /dev/null
+++ b/Doc/data/python3.10.abi
@@ -0,0 +1,20719 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 505f1203dd1bdd..89b64e6c083155 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -1073,8 +1073,8 @@ PyInterpreterState_New:PyInterpreterState*:::
PyIter_Check:int:::
PyIter_Check:PyObject*:o:0:
-PyAiter_Check:int:::
-PyAiter_Check:PyObject*:o:0:
+PyAIter_Check:int:::
+PyAIter_Check:PyObject*:o:0:
PyIter_Next:PyObject*::+1:
PyIter_Next:PyObject*:o:0:
@@ -1571,6 +1571,21 @@ PyOS_FSPath:PyObject*:path:0:
PyObject_ASCII:PyObject*::+1:
PyObject_ASCII:PyObject*:o:0:
+PyObject_AsCharBuffer:int:::
+PyObject_AsCharBuffer:PyObject*:obj:0:
+PyObject_AsCharBuffer:const char**:buffer::
+PyObject_AsCharBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_AsReadBuffer:int:::
+PyObject_AsReadBuffer:PyObject*:obj:0:
+PyObject_AsReadBuffer:const void**:buffer::
+PyObject_AsReadBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_AsWriteBuffer:int:::
+PyObject_AsWriteBuffer:PyObject*:obj:0:
+PyObject_AsWriteBuffer:void**:buffer::
+PyObject_AsWriteBuffer:Py_ssize_t*:buffer_len::
+
PyObject_Bytes:PyObject*::+1:
PyObject_Bytes:PyObject*:o:0:
@@ -1606,6 +1621,9 @@ PyObject_CallObject:PyObject*:args:0:
PyObject_CheckBuffer:int:::
PyObject_CheckBuffer:PyObject*:obj:0:
+PyObject_CheckReadBuffer:int:::
+PyObject_CheckReadBuffer:PyObject*:o:0:
+
PyObject_DelAttr:int:::
PyObject_DelAttr:PyObject*:o:0:
PyObject_DelAttr:PyObject*:attr_name:0:
@@ -1682,8 +1700,8 @@ PyObject_GetItem:PyObject*:key:0:
PyObject_GetIter:PyObject*::+1:
PyObject_GetIter:PyObject*:o:0:
-PyObject_GetAiter:PyObject*::+1:
-PyObject_GetAiter:PyObject*:o:0:
+PyObject_GetAIter:PyObject*::+1:
+PyObject_GetAIter:PyObject*:o:0:
PyObject_HasAttr:int:::
PyObject_HasAttr:PyObject*:o:0:
@@ -1791,32 +1809,6 @@ PyObject_TypeCheck:int:::
PyObject_TypeCheck:PyObject*:o:0:
PyObject_TypeCheck:PyTypeObject*:type:0:
-PyParser_SimpleParseFile:struct _node*:::
-PyParser_SimpleParseFile:FILE*:fp::
-PyParser_SimpleParseFile:const char*:filename::
-PyParser_SimpleParseFile:int:start::
-
-PyParser_SimpleParseFileFlags:struct _node*:::
-PyParser_SimpleParseFileFlags:FILE*:fp::
-PyParser_SimpleParseFileFlags:const char*:filename::
-PyParser_SimpleParseFileFlags:int:start::
-PyParser_SimpleParseFileFlags:int:flags::
-
-PyParser_SimpleParseString:struct _node*:::
-PyParser_SimpleParseString:const char*:str::
-PyParser_SimpleParseString:int:start::
-
-PyParser_SimpleParseStringFlags:struct _node*:::
-PyParser_SimpleParseStringFlags:const char*:str::
-PyParser_SimpleParseStringFlags:int:start::
-PyParser_SimpleParseStringFlags:int:flags::
-
-PyParser_SimpleParseStringFlagsFilename:struct _node*:::
-PyParser_SimpleParseStringFlagsFilename:const char*:str::
-PyParser_SimpleParseStringFlagsFilename:const char*:filename::
-PyParser_SimpleParseStringFlagsFilename:int:start::
-PyParser_SimpleParseStringFlagsFilename:int:flags::
-
PyRun_AnyFile:int:::
PyRun_AnyFile:FILE*:fp::
PyRun_AnyFile:const char*:filename::
diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index 833228f7fd755d..ea102b989c8649 100644
--- a/Doc/data/stable_abi.dat
+++ b/Doc/data/stable_abi.dat
@@ -1,953 +1,863 @@
-# Generated by Tools/scripts/stable_abi.py
-
-METH_CLASS
-METH_COEXIST
-METH_FASTCALL
-METH_METHOD
-METH_NOARGS
-METH_O
-METH_STATIC
-METH_VARARGS
-PyAiter_Check
-PyArg_Parse
-PyArg_ParseTuple
-PyArg_ParseTupleAndKeywords
-PyArg_UnpackTuple
-PyArg_VaParse
-PyArg_VaParseTupleAndKeywords
-PyArg_ValidateKeywordArguments
-PyBaseObject_Type
-PyBool_FromLong
-PyBool_Type
-PyByteArrayIter_Type
-PyByteArray_AsString
-PyByteArray_Concat
-PyByteArray_FromObject
-PyByteArray_FromStringAndSize
-PyByteArray_Resize
-PyByteArray_Size
-PyByteArray_Type
-PyBytesIter_Type
-PyBytes_AsString
-PyBytes_AsStringAndSize
-PyBytes_Concat
-PyBytes_ConcatAndDel
-PyBytes_DecodeEscape
-PyBytes_FromFormat
-PyBytes_FromFormatV
-PyBytes_FromObject
-PyBytes_FromString
-PyBytes_FromStringAndSize
-PyBytes_Repr
-PyBytes_Size
-PyBytes_Type
-PyCFunction
-PyCFunctionWithKeywords
-PyCFunction_Call
-PyCFunction_GetFlags
-PyCFunction_GetFunction
-PyCFunction_GetSelf
-PyCFunction_New
-PyCFunction_NewEx
-PyCFunction_Type
-PyCMethod_New
-PyCallIter_New
-PyCallIter_Type
-PyCallable_Check
-PyCapsule_Destructor
-PyCapsule_GetContext
-PyCapsule_GetDestructor
-PyCapsule_GetName
-PyCapsule_GetPointer
-PyCapsule_Import
-PyCapsule_IsValid
-PyCapsule_New
-PyCapsule_SetContext
-PyCapsule_SetDestructor
-PyCapsule_SetName
-PyCapsule_SetPointer
-PyCapsule_Type
-PyClassMethodDescr_Type
-PyCodec_BackslashReplaceErrors
-PyCodec_Decode
-PyCodec_Decoder
-PyCodec_Encode
-PyCodec_Encoder
-PyCodec_IgnoreErrors
-PyCodec_IncrementalDecoder
-PyCodec_IncrementalEncoder
-PyCodec_KnownEncoding
-PyCodec_LookupError
-PyCodec_NameReplaceErrors
-PyCodec_Register
-PyCodec_RegisterError
-PyCodec_ReplaceErrors
-PyCodec_StreamReader
-PyCodec_StreamWriter
-PyCodec_StrictErrors
-PyCodec_Unregister
-PyCodec_XMLCharRefReplaceErrors
-PyComplex_FromDoubles
-PyComplex_ImagAsDouble
-PyComplex_RealAsDouble
-PyComplex_Type
-PyDescr_NewClassMethod
-PyDescr_NewGetSet
-PyDescr_NewMember
-PyDescr_NewMethod
-PyDictItems_Type
-PyDictIterItem_Type
-PyDictIterKey_Type
-PyDictIterValue_Type
-PyDictKeys_Type
-PyDictProxy_New
-PyDictProxy_Type
-PyDictRevIterItem_Type
-PyDictRevIterKey_Type
-PyDictRevIterValue_Type
-PyDictValues_Type
-PyDict_Clear
-PyDict_Contains
-PyDict_Copy
-PyDict_DelItem
-PyDict_DelItemString
-PyDict_GetItem
-PyDict_GetItemString
-PyDict_GetItemWithError
-PyDict_Items
-PyDict_Keys
-PyDict_Merge
-PyDict_MergeFromSeq2
-PyDict_New
-PyDict_Next
-PyDict_SetItem
-PyDict_SetItemString
-PyDict_Size
-PyDict_Type
-PyDict_Update
-PyDict_Values
-PyEllipsis_Type
-PyEnum_Type
-PyErr_BadArgument
-PyErr_BadInternalCall
-PyErr_CheckSignals
-PyErr_Clear
-PyErr_Display
-PyErr_ExceptionMatches
-PyErr_Fetch
-PyErr_Format
-PyErr_FormatV
-PyErr_GetExcInfo
-PyErr_GivenExceptionMatches
-PyErr_NewException
-PyErr_NewExceptionWithDoc
-PyErr_NoMemory
-PyErr_NormalizeException
-PyErr_Occurred
-PyErr_Print
-PyErr_PrintEx
-PyErr_ProgramText
-PyErr_ResourceWarning
-PyErr_Restore
-PyErr_SetExcFromWindowsErr
-PyErr_SetExcFromWindowsErrWithFilename
-PyErr_SetExcFromWindowsErrWithFilenameObject
-PyErr_SetExcFromWindowsErrWithFilenameObjects
-PyErr_SetExcInfo
-PyErr_SetFromErrno
-PyErr_SetFromErrnoWithFilename
-PyErr_SetFromErrnoWithFilenameObject
-PyErr_SetFromErrnoWithFilenameObjects
-PyErr_SetFromWindowsErr
-PyErr_SetFromWindowsErrWithFilename
-PyErr_SetImportError
-PyErr_SetImportErrorSubclass
-PyErr_SetInterrupt
-PyErr_SetInterruptEx
-PyErr_SetNone
-PyErr_SetObject
-PyErr_SetString
-PyErr_SyntaxLocation
-PyErr_SyntaxLocationEx
-PyErr_WarnEx
-PyErr_WarnExplicit
-PyErr_WarnFormat
-PyErr_WriteUnraisable
-PyEval_AcquireLock
-PyEval_AcquireThread
-PyEval_CallFunction
-PyEval_CallMethod
-PyEval_CallObjectWithKeywords
-PyEval_EvalCode
-PyEval_EvalCodeEx
-PyEval_EvalFrame
-PyEval_EvalFrameEx
-PyEval_GetBuiltins
-PyEval_GetFrame
-PyEval_GetFuncDesc
-PyEval_GetFuncName
-PyEval_GetGlobals
-PyEval_GetLocals
-PyEval_InitThreads
-PyEval_ReleaseLock
-PyEval_ReleaseThread
-PyEval_RestoreThread
-PyEval_SaveThread
-PyEval_ThreadsInitialized
-PyExc_ArithmeticError
-PyExc_AssertionError
-PyExc_AttributeError
-PyExc_BaseException
-PyExc_BlockingIOError
-PyExc_BrokenPipeError
-PyExc_BufferError
-PyExc_BytesWarning
-PyExc_ChildProcessError
-PyExc_ConnectionAbortedError
-PyExc_ConnectionError
-PyExc_ConnectionRefusedError
-PyExc_ConnectionResetError
-PyExc_DeprecationWarning
-PyExc_EOFError
-PyExc_EncodingWarning
-PyExc_EnvironmentError
-PyExc_Exception
-PyExc_FileExistsError
-PyExc_FileNotFoundError
-PyExc_FloatingPointError
-PyExc_FutureWarning
-PyExc_GeneratorExit
-PyExc_IOError
-PyExc_ImportError
-PyExc_ImportWarning
-PyExc_IndentationError
-PyExc_IndexError
-PyExc_InterruptedError
-PyExc_IsADirectoryError
-PyExc_KeyError
-PyExc_KeyboardInterrupt
-PyExc_LookupError
-PyExc_MemoryError
-PyExc_ModuleNotFoundError
-PyExc_NameError
-PyExc_NotADirectoryError
-PyExc_NotImplementedError
-PyExc_OSError
-PyExc_OverflowError
-PyExc_PendingDeprecationWarning
-PyExc_PermissionError
-PyExc_ProcessLookupError
-PyExc_RecursionError
-PyExc_ReferenceError
-PyExc_ResourceWarning
-PyExc_RuntimeError
-PyExc_RuntimeWarning
-PyExc_StopAsyncIteration
-PyExc_StopIteration
-PyExc_SyntaxError
-PyExc_SyntaxWarning
-PyExc_SystemError
-PyExc_SystemExit
-PyExc_TabError
-PyExc_TimeoutError
-PyExc_TypeError
-PyExc_UnboundLocalError
-PyExc_UnicodeDecodeError
-PyExc_UnicodeEncodeError
-PyExc_UnicodeError
-PyExc_UnicodeTranslateError
-PyExc_UnicodeWarning
-PyExc_UserWarning
-PyExc_ValueError
-PyExc_Warning
-PyExc_WindowsError
-PyExc_ZeroDivisionError
-PyExceptionClass_Name
-PyException_GetCause
-PyException_GetContext
-PyException_GetTraceback
-PyException_SetCause
-PyException_SetContext
-PyException_SetTraceback
-PyFile_FromFd
-PyFile_GetLine
-PyFile_WriteObject
-PyFile_WriteString
-PyFilter_Type
-PyFloat_AsDouble
-PyFloat_FromDouble
-PyFloat_FromString
-PyFloat_GetInfo
-PyFloat_GetMax
-PyFloat_GetMin
-PyFloat_Type
-PyFrame_GetCode
-PyFrame_GetLineNumber
-PyFrozenSet_New
-PyFrozenSet_Type
-PyGC_Collect
-PyGC_Disable
-PyGC_Enable
-PyGC_IsEnabled
-PyGILState_Ensure
-PyGILState_GetThisThreadState
-PyGILState_Release
-PyGILState_STATE
-PyGetSetDef
-PyGetSetDescr_Type
-PyImport_AddModule
-PyImport_AddModuleObject
-PyImport_AppendInittab
-PyImport_ExecCodeModule
-PyImport_ExecCodeModuleEx
-PyImport_ExecCodeModuleObject
-PyImport_ExecCodeModuleWithPathnames
-PyImport_GetImporter
-PyImport_GetMagicNumber
-PyImport_GetMagicTag
-PyImport_GetModule
-PyImport_GetModuleDict
-PyImport_Import
-PyImport_ImportFrozenModule
-PyImport_ImportFrozenModuleObject
-PyImport_ImportModule
-PyImport_ImportModuleLevel
-PyImport_ImportModuleLevelObject
-PyImport_ImportModuleNoBlock
-PyImport_ReloadModule
-PyIndex_Check
-PyInterpreterState
-PyInterpreterState_Clear
-PyInterpreterState_Delete
-PyInterpreterState_Get
-PyInterpreterState_GetDict
-PyInterpreterState_GetID
-PyInterpreterState_New
-PyIter_Check
-PyIter_Next
-PyIter_Send
-PyListIter_Type
-PyListRevIter_Type
-PyList_Append
-PyList_AsTuple
-PyList_GetItem
-PyList_GetSlice
-PyList_Insert
-PyList_New
-PyList_Reverse
-PyList_SetItem
-PyList_SetSlice
-PyList_Size
-PyList_Sort
-PyList_Type
-PyLongObject
-PyLongRangeIter_Type
-PyLong_AsDouble
-PyLong_AsLong
-PyLong_AsLongAndOverflow
-PyLong_AsLongLong
-PyLong_AsLongLongAndOverflow
-PyLong_AsSize_t
-PyLong_AsSsize_t
-PyLong_AsUnsignedLong
-PyLong_AsUnsignedLongLong
-PyLong_AsUnsignedLongLongMask
-PyLong_AsUnsignedLongMask
-PyLong_AsVoidPtr
-PyLong_FromDouble
-PyLong_FromLong
-PyLong_FromLongLong
-PyLong_FromSize_t
-PyLong_FromSsize_t
-PyLong_FromString
-PyLong_FromUnsignedLong
-PyLong_FromUnsignedLongLong
-PyLong_FromVoidPtr
-PyLong_GetInfo
-PyLong_Type
-PyMap_Type
-PyMapping_Check
-PyMapping_GetItemString
-PyMapping_HasKey
-PyMapping_HasKeyString
-PyMapping_Items
-PyMapping_Keys
-PyMapping_Length
-PyMapping_SetItemString
-PyMapping_Size
-PyMapping_Values
-PyMem_Calloc
-PyMem_Free
-PyMem_Malloc
-PyMem_Realloc
-PyMemberDef
-PyMemberDescr_Type
-PyMemoryView_FromMemory
-PyMemoryView_FromObject
-PyMemoryView_GetContiguous
-PyMemoryView_Type
-PyMethodDef
-PyMethodDescr_Type
-PyModuleDef
-PyModuleDef_Base
-PyModuleDef_Init
-PyModuleDef_Type
-PyModule_AddFunctions
-PyModule_AddIntConstant
-PyModule_AddObject
-PyModule_AddObjectRef
-PyModule_AddStringConstant
-PyModule_AddType
-PyModule_Create2
-PyModule_ExecDef
-PyModule_FromDefAndSpec2
-PyModule_GetDef
-PyModule_GetDict
-PyModule_GetFilename
-PyModule_GetFilenameObject
-PyModule_GetName
-PyModule_GetNameObject
-PyModule_GetState
-PyModule_New
-PyModule_NewObject
-PyModule_SetDocString
-PyModule_Type
-PyNumber_Absolute
-PyNumber_Add
-PyNumber_And
-PyNumber_AsSsize_t
-PyNumber_Check
-PyNumber_Divmod
-PyNumber_Float
-PyNumber_FloorDivide
-PyNumber_InPlaceAdd
-PyNumber_InPlaceAnd
-PyNumber_InPlaceFloorDivide
-PyNumber_InPlaceLshift
-PyNumber_InPlaceMatrixMultiply
-PyNumber_InPlaceMultiply
-PyNumber_InPlaceOr
-PyNumber_InPlacePower
-PyNumber_InPlaceRemainder
-PyNumber_InPlaceRshift
-PyNumber_InPlaceSubtract
-PyNumber_InPlaceTrueDivide
-PyNumber_InPlaceXor
-PyNumber_Index
-PyNumber_Invert
-PyNumber_Long
-PyNumber_Lshift
-PyNumber_MatrixMultiply
-PyNumber_Multiply
-PyNumber_Negative
-PyNumber_Or
-PyNumber_Positive
-PyNumber_Power
-PyNumber_Remainder
-PyNumber_Rshift
-PyNumber_Subtract
-PyNumber_ToBase
-PyNumber_TrueDivide
-PyNumber_Xor
-PyOS_AfterFork
-PyOS_AfterFork_Child
-PyOS_AfterFork_Parent
-PyOS_BeforeFork
-PyOS_CheckStack
-PyOS_FSPath
-PyOS_InputHook
-PyOS_InterruptOccurred
-PyOS_double_to_string
-PyOS_getsig
-PyOS_mystricmp
-PyOS_mystrnicmp
-PyOS_setsig
-PyOS_sighandler_t
-PyOS_snprintf
-PyOS_string_to_double
-PyOS_strtol
-PyOS_strtoul
-PyOS_vsnprintf
-PyObject
-PyObject_ASCII
-PyObject_AsFileDescriptor
-PyObject_Bytes
-PyObject_Call
-PyObject_CallFunction
-PyObject_CallFunctionObjArgs
-PyObject_CallMethod
-PyObject_CallMethodObjArgs
-PyObject_CallNoArgs
-PyObject_CallObject
-PyObject_Calloc
-PyObject_ClearWeakRefs
-PyObject_DelItem
-PyObject_DelItemString
-PyObject_Dir
-PyObject_Format
-PyObject_Free
-PyObject_GC_Del
-PyObject_GC_IsFinalized
-PyObject_GC_IsTracked
-PyObject_GC_Track
-PyObject_GC_UnTrack
-PyObject_GenericGetAttr
-PyObject_GenericGetDict
-PyObject_GenericSetAttr
-PyObject_GenericSetDict
-PyObject_GetAiter
-PyObject_GetAttr
-PyObject_GetAttrString
-PyObject_GetItem
-PyObject_GetIter
-PyObject_HasAttr
-PyObject_HasAttrString
-PyObject_Hash
-PyObject_HashNotImplemented
-PyObject_Init
-PyObject_InitVar
-PyObject_IsInstance
-PyObject_IsSubclass
-PyObject_IsTrue
-PyObject_Length
-PyObject_Malloc
-PyObject_Not
-PyObject_Realloc
-PyObject_Repr
-PyObject_RichCompare
-PyObject_RichCompareBool
-PyObject_SelfIter
-PyObject_SetAttr
-PyObject_SetAttrString
-PyObject_SetItem
-PyObject_Size
-PyObject_Str
-PyObject_Type
-PyProperty_Type
-PyRangeIter_Type
-PyRange_Type
-PyReversed_Type
-PySeqIter_New
-PySeqIter_Type
-PySequence_Check
-PySequence_Concat
-PySequence_Contains
-PySequence_Count
-PySequence_DelItem
-PySequence_DelSlice
-PySequence_Fast
-PySequence_GetItem
-PySequence_GetSlice
-PySequence_In
-PySequence_InPlaceConcat
-PySequence_InPlaceRepeat
-PySequence_Index
-PySequence_Length
-PySequence_List
-PySequence_Repeat
-PySequence_SetItem
-PySequence_SetSlice
-PySequence_Size
-PySequence_Tuple
-PySetIter_Type
-PySet_Add
-PySet_Clear
-PySet_Contains
-PySet_Discard
-PySet_New
-PySet_Pop
-PySet_Size
-PySet_Type
-PySlice_AdjustIndices
-PySlice_GetIndices
-PySlice_GetIndicesEx
-PySlice_New
-PySlice_Type
-PySlice_Unpack
-PyState_AddModule
-PyState_FindModule
-PyState_RemoveModule
-PyStructSequence_Desc
-PyStructSequence_Field
-PyStructSequence_GetItem
-PyStructSequence_New
-PyStructSequence_NewType
-PyStructSequence_SetItem
-PySuper_Type
-PySys_AddWarnOption
-PySys_AddWarnOptionUnicode
-PySys_AddXOption
-PySys_FormatStderr
-PySys_FormatStdout
-PySys_GetObject
-PySys_GetXOptions
-PySys_HasWarnOptions
-PySys_ResetWarnOptions
-PySys_SetArgv
-PySys_SetArgvEx
-PySys_SetObject
-PySys_SetPath
-PySys_WriteStderr
-PySys_WriteStdout
-PyThreadState
-PyThreadState_Clear
-PyThreadState_Delete
-PyThreadState_Get
-PyThreadState_GetDict
-PyThreadState_GetFrame
-PyThreadState_GetID
-PyThreadState_GetInterpreter
-PyThreadState_New
-PyThreadState_SetAsyncExc
-PyThreadState_Swap
-PyThread_GetInfo
-PyThread_ReInitTLS
-PyThread_acquire_lock
-PyThread_acquire_lock_timed
-PyThread_allocate_lock
-PyThread_create_key
-PyThread_delete_key
-PyThread_delete_key_value
-PyThread_exit_thread
-PyThread_free_lock
-PyThread_get_key_value
-PyThread_get_stacksize
-PyThread_get_thread_ident
-PyThread_get_thread_native_id
-PyThread_init_thread
-PyThread_release_lock
-PyThread_set_key_value
-PyThread_set_stacksize
-PyThread_start_new_thread
-PyThread_tss_alloc
-PyThread_tss_create
-PyThread_tss_delete
-PyThread_tss_free
-PyThread_tss_get
-PyThread_tss_is_created
-PyThread_tss_set
-PyTraceBack_Here
-PyTraceBack_Print
-PyTraceBack_Type
-PyTupleIter_Type
-PyTuple_GetItem
-PyTuple_GetSlice
-PyTuple_New
-PyTuple_Pack
-PyTuple_SetItem
-PyTuple_Size
-PyTuple_Type
-PyTypeObject
-PyType_ClearCache
-PyType_FromModuleAndSpec
-PyType_FromSpec
-PyType_FromSpecWithBases
-PyType_GenericAlloc
-PyType_GenericNew
-PyType_GetFlags
-PyType_GetModule
-PyType_GetModuleState
-PyType_GetSlot
-PyType_IsSubtype
-PyType_Modified
-PyType_Ready
-PyType_Slot
-PyType_Spec
-PyType_Type
-PyUnicodeDecodeError_Create
-PyUnicodeDecodeError_GetEncoding
-PyUnicodeDecodeError_GetEnd
-PyUnicodeDecodeError_GetObject
-PyUnicodeDecodeError_GetReason
-PyUnicodeDecodeError_GetStart
-PyUnicodeDecodeError_SetEnd
-PyUnicodeDecodeError_SetReason
-PyUnicodeDecodeError_SetStart
-PyUnicodeEncodeError_GetEncoding
-PyUnicodeEncodeError_GetEnd
-PyUnicodeEncodeError_GetObject
-PyUnicodeEncodeError_GetReason
-PyUnicodeEncodeError_GetStart
-PyUnicodeEncodeError_SetEnd
-PyUnicodeEncodeError_SetReason
-PyUnicodeEncodeError_SetStart
-PyUnicodeIter_Type
-PyUnicodeTranslateError_GetEnd
-PyUnicodeTranslateError_GetObject
-PyUnicodeTranslateError_GetReason
-PyUnicodeTranslateError_GetStart
-PyUnicodeTranslateError_SetEnd
-PyUnicodeTranslateError_SetReason
-PyUnicodeTranslateError_SetStart
-PyUnicode_Append
-PyUnicode_AppendAndDel
-PyUnicode_AsASCIIString
-PyUnicode_AsCharmapString
-PyUnicode_AsDecodedObject
-PyUnicode_AsDecodedUnicode
-PyUnicode_AsEncodedObject
-PyUnicode_AsEncodedString
-PyUnicode_AsEncodedUnicode
-PyUnicode_AsLatin1String
-PyUnicode_AsMBCSString
-PyUnicode_AsRawUnicodeEscapeString
-PyUnicode_AsUCS4
-PyUnicode_AsUCS4Copy
-PyUnicode_AsUTF16String
-PyUnicode_AsUTF32String
-PyUnicode_AsUTF8AndSize
-PyUnicode_AsUTF8String
-PyUnicode_AsUnicodeEscapeString
-PyUnicode_AsWideChar
-PyUnicode_AsWideCharString
-PyUnicode_BuildEncodingMap
-PyUnicode_Compare
-PyUnicode_CompareWithASCIIString
-PyUnicode_Concat
-PyUnicode_Contains
-PyUnicode_Count
-PyUnicode_Decode
-PyUnicode_DecodeASCII
-PyUnicode_DecodeCharmap
-PyUnicode_DecodeCodePageStateful
-PyUnicode_DecodeFSDefault
-PyUnicode_DecodeFSDefaultAndSize
-PyUnicode_DecodeLatin1
-PyUnicode_DecodeLocale
-PyUnicode_DecodeLocaleAndSize
-PyUnicode_DecodeMBCS
-PyUnicode_DecodeMBCSStateful
-PyUnicode_DecodeRawUnicodeEscape
-PyUnicode_DecodeUTF16
-PyUnicode_DecodeUTF16Stateful
-PyUnicode_DecodeUTF32
-PyUnicode_DecodeUTF32Stateful
-PyUnicode_DecodeUTF7
-PyUnicode_DecodeUTF7Stateful
-PyUnicode_DecodeUTF8
-PyUnicode_DecodeUTF8Stateful
-PyUnicode_DecodeUnicodeEscape
-PyUnicode_EncodeCodePage
-PyUnicode_EncodeFSDefault
-PyUnicode_EncodeLocale
-PyUnicode_FSConverter
-PyUnicode_FSDecoder
-PyUnicode_Find
-PyUnicode_FindChar
-PyUnicode_Format
-PyUnicode_FromEncodedObject
-PyUnicode_FromFormat
-PyUnicode_FromFormatV
-PyUnicode_FromObject
-PyUnicode_FromOrdinal
-PyUnicode_FromString
-PyUnicode_FromStringAndSize
-PyUnicode_FromWideChar
-PyUnicode_GetDefaultEncoding
-PyUnicode_GetLength
-PyUnicode_GetSize
-PyUnicode_InternFromString
-PyUnicode_InternImmortal
-PyUnicode_InternInPlace
-PyUnicode_IsIdentifier
-PyUnicode_Join
-PyUnicode_Partition
-PyUnicode_RPartition
-PyUnicode_RSplit
-PyUnicode_ReadChar
-PyUnicode_Replace
-PyUnicode_Resize
-PyUnicode_RichCompare
-PyUnicode_Split
-PyUnicode_Splitlines
-PyUnicode_Substring
-PyUnicode_Tailmatch
-PyUnicode_Translate
-PyUnicode_Type
-PyUnicode_WriteChar
-PyVarObject
-PyWeakReference
-PyWeakref_GetObject
-PyWeakref_NewProxy
-PyWeakref_NewRef
-PyWrapperDescr_Type
-PyWrapper_New
-PyZip_Type
-Py_AddPendingCall
-Py_AtExit
-Py_BEGIN_ALLOW_THREADS
-Py_BLOCK_THREADS
-Py_BuildValue
-Py_BytesMain
-Py_CompileString
-Py_DecRef
-Py_DecodeLocale
-Py_END_ALLOW_THREADS
-Py_EncodeLocale
-Py_EndInterpreter
-Py_EnterRecursiveCall
-Py_Exit
-Py_FatalError
-Py_FileSystemDefaultEncodeErrors
-Py_FileSystemDefaultEncoding
-Py_Finalize
-Py_FinalizeEx
-Py_FrozenMain
-Py_GenericAlias
-Py_GenericAliasType
-Py_GetBuildInfo
-Py_GetCompiler
-Py_GetCopyright
-Py_GetExecPrefix
-Py_GetPath
-Py_GetPlatform
-Py_GetPrefix
-Py_GetProgramFullPath
-Py_GetProgramName
-Py_GetPythonHome
-Py_GetRecursionLimit
-Py_GetVersion
-Py_HasFileSystemDefaultEncoding
-Py_IncRef
-Py_Initialize
-Py_InitializeEx
-Py_Is
-Py_IsFalse
-Py_IsInitialized
-Py_IsNone
-Py_IsTrue
-Py_LeaveRecursiveCall
-Py_Main
-Py_MakePendingCalls
-Py_NewInterpreter
-Py_NewRef
-Py_ReprEnter
-Py_ReprLeave
-Py_SetPath
-Py_SetProgramName
-Py_SetPythonHome
-Py_SetRecursionLimit
-Py_TPFLAGS_BASETYPE
-Py_TPFLAGS_DEFAULT
-Py_TPFLAGS_HAVE_GC
-Py_TPFLAGS_METHOD_DESCRIPTOR
-Py_UCS4
-Py_UNBLOCK_THREADS
-Py_UTF8Mode
-Py_VaBuildValue
-Py_XNewRef
-Py_am_aiter
-Py_am_anext
-Py_am_await
-Py_am_send
-Py_intptr_t
-Py_mp_ass_subscript
-Py_mp_length
-Py_mp_subscript
-Py_nb_absolute
-Py_nb_add
-Py_nb_and
-Py_nb_bool
-Py_nb_divmod
-Py_nb_float
-Py_nb_floor_divide
-Py_nb_index
-Py_nb_inplace_add
-Py_nb_inplace_and
-Py_nb_inplace_floor_divide
-Py_nb_inplace_lshift
-Py_nb_inplace_matrix_multiply
-Py_nb_inplace_multiply
-Py_nb_inplace_or
-Py_nb_inplace_power
-Py_nb_inplace_remainder
-Py_nb_inplace_rshift
-Py_nb_inplace_subtract
-Py_nb_inplace_true_divide
-Py_nb_inplace_xor
-Py_nb_int
-Py_nb_invert
-Py_nb_lshift
-Py_nb_matrix_multiply
-Py_nb_multiply
-Py_nb_negative
-Py_nb_or
-Py_nb_positive
-Py_nb_power
-Py_nb_remainder
-Py_nb_rshift
-Py_nb_subtract
-Py_nb_true_divide
-Py_nb_xor
-Py_sq_ass_item
-Py_sq_concat
-Py_sq_contains
-Py_sq_inplace_concat
-Py_sq_inplace_repeat
-Py_sq_item
-Py_sq_length
-Py_sq_repeat
-Py_ssize_t
-Py_tp_alloc
-Py_tp_base
-Py_tp_bases
-Py_tp_call
-Py_tp_clear
-Py_tp_dealloc
-Py_tp_del
-Py_tp_descr_get
-Py_tp_descr_set
-Py_tp_doc
-Py_tp_finalize
-Py_tp_free
-Py_tp_getattr
-Py_tp_getattro
-Py_tp_getset
-Py_tp_hash
-Py_tp_init
-Py_tp_is_gc
-Py_tp_iter
-Py_tp_iternext
-Py_tp_members
-Py_tp_methods
-Py_tp_new
-Py_tp_repr
-Py_tp_richcompare
-Py_tp_setattr
-Py_tp_setattro
-Py_tp_str
-Py_tp_traverse
-Py_uintptr_t
-_frame
-_node
-allocfunc
-binaryfunc
-descrgetfunc
-descrsetfunc
-destructor
-getattrfunc
-getattrofunc
-getiterfunc
-getter
-hashfunc
-initproc
-inquiry
-iternextfunc
-lenfunc
-newfunc
-objobjargproc
-objobjproc
-reprfunc
-richcmpfunc
-setattrfunc
-setattrofunc
-setter
-ssizeargfunc
-ssizeobjargproc
-ssizessizeargfunc
-ssizessizeobjargproc
-symtable
-ternaryfunc
-traverseproc
-unaryfunc
-visitproc
+role,name,added,ifdef_note
+function,PyAIter_Check,3.10,
+function,PyArg_Parse,3.2,
+function,PyArg_ParseTuple,3.2,
+function,PyArg_ParseTupleAndKeywords,3.2,
+function,PyArg_UnpackTuple,3.2,
+function,PyArg_VaParse,3.2,
+function,PyArg_VaParseTupleAndKeywords,3.2,
+function,PyArg_ValidateKeywordArguments,3.2,
+var,PyBaseObject_Type,3.2,
+function,PyBool_FromLong,3.2,
+var,PyBool_Type,3.2,
+var,PyByteArrayIter_Type,3.2,
+function,PyByteArray_AsString,3.2,
+function,PyByteArray_Concat,3.2,
+function,PyByteArray_FromObject,3.2,
+function,PyByteArray_FromStringAndSize,3.2,
+function,PyByteArray_Resize,3.2,
+function,PyByteArray_Size,3.2,
+var,PyByteArray_Type,3.2,
+var,PyBytesIter_Type,3.2,
+function,PyBytes_AsString,3.2,
+function,PyBytes_AsStringAndSize,3.2,
+function,PyBytes_Concat,3.2,
+function,PyBytes_ConcatAndDel,3.2,
+function,PyBytes_DecodeEscape,3.2,
+function,PyBytes_FromFormat,3.2,
+function,PyBytes_FromFormatV,3.2,
+function,PyBytes_FromObject,3.2,
+function,PyBytes_FromString,3.2,
+function,PyBytes_FromStringAndSize,3.2,
+function,PyBytes_Repr,3.2,
+function,PyBytes_Size,3.2,
+var,PyBytes_Type,3.2,
+type,PyCFunction,3.2,
+type,PyCFunctionWithKeywords,3.2,
+function,PyCFunction_Call,3.2,
+function,PyCFunction_GetFlags,3.2,
+function,PyCFunction_GetFunction,3.2,
+function,PyCFunction_GetSelf,3.2,
+function,PyCFunction_New,3.4,
+function,PyCFunction_NewEx,3.2,
+var,PyCFunction_Type,3.2,
+function,PyCMethod_New,3.9,
+function,PyCallIter_New,3.2,
+var,PyCallIter_Type,3.2,
+function,PyCallable_Check,3.2,
+type,PyCapsule_Destructor,3.2,
+function,PyCapsule_GetContext,3.2,
+function,PyCapsule_GetDestructor,3.2,
+function,PyCapsule_GetName,3.2,
+function,PyCapsule_GetPointer,3.2,
+function,PyCapsule_Import,3.2,
+function,PyCapsule_IsValid,3.2,
+function,PyCapsule_New,3.2,
+function,PyCapsule_SetContext,3.2,
+function,PyCapsule_SetDestructor,3.2,
+function,PyCapsule_SetName,3.2,
+function,PyCapsule_SetPointer,3.2,
+var,PyCapsule_Type,3.2,
+var,PyClassMethodDescr_Type,3.2,
+function,PyCodec_BackslashReplaceErrors,3.2,
+function,PyCodec_Decode,3.2,
+function,PyCodec_Decoder,3.2,
+function,PyCodec_Encode,3.2,
+function,PyCodec_Encoder,3.2,
+function,PyCodec_IgnoreErrors,3.2,
+function,PyCodec_IncrementalDecoder,3.2,
+function,PyCodec_IncrementalEncoder,3.2,
+function,PyCodec_KnownEncoding,3.2,
+function,PyCodec_LookupError,3.2,
+function,PyCodec_NameReplaceErrors,3.7,
+function,PyCodec_Register,3.2,
+function,PyCodec_RegisterError,3.2,
+function,PyCodec_ReplaceErrors,3.2,
+function,PyCodec_StreamReader,3.2,
+function,PyCodec_StreamWriter,3.2,
+function,PyCodec_StrictErrors,3.2,
+function,PyCodec_Unregister,3.10,
+function,PyCodec_XMLCharRefReplaceErrors,3.2,
+function,PyComplex_FromDoubles,3.2,
+function,PyComplex_ImagAsDouble,3.2,
+function,PyComplex_RealAsDouble,3.2,
+var,PyComplex_Type,3.2,
+function,PyDescr_NewClassMethod,3.2,
+function,PyDescr_NewGetSet,3.2,
+function,PyDescr_NewMember,3.2,
+function,PyDescr_NewMethod,3.2,
+var,PyDictItems_Type,3.2,
+var,PyDictIterItem_Type,3.2,
+var,PyDictIterKey_Type,3.2,
+var,PyDictIterValue_Type,3.2,
+var,PyDictKeys_Type,3.2,
+function,PyDictProxy_New,3.2,
+var,PyDictProxy_Type,3.2,
+var,PyDictRevIterItem_Type,3.8,
+var,PyDictRevIterKey_Type,3.8,
+var,PyDictRevIterValue_Type,3.8,
+var,PyDictValues_Type,3.2,
+function,PyDict_Clear,3.2,
+function,PyDict_Contains,3.2,
+function,PyDict_Copy,3.2,
+function,PyDict_DelItem,3.2,
+function,PyDict_DelItemString,3.2,
+function,PyDict_GetItem,3.2,
+function,PyDict_GetItemString,3.2,
+function,PyDict_GetItemWithError,3.2,
+function,PyDict_Items,3.2,
+function,PyDict_Keys,3.2,
+function,PyDict_Merge,3.2,
+function,PyDict_MergeFromSeq2,3.2,
+function,PyDict_New,3.2,
+function,PyDict_Next,3.2,
+function,PyDict_SetItem,3.2,
+function,PyDict_SetItemString,3.2,
+function,PyDict_Size,3.2,
+var,PyDict_Type,3.2,
+function,PyDict_Update,3.2,
+function,PyDict_Values,3.2,
+var,PyEllipsis_Type,3.2,
+var,PyEnum_Type,3.2,
+function,PyErr_BadArgument,3.2,
+function,PyErr_BadInternalCall,3.2,
+function,PyErr_CheckSignals,3.2,
+function,PyErr_Clear,3.2,
+function,PyErr_Display,3.2,
+function,PyErr_ExceptionMatches,3.2,
+function,PyErr_Fetch,3.2,
+function,PyErr_Format,3.2,
+function,PyErr_FormatV,3.5,
+function,PyErr_GetExcInfo,3.7,
+function,PyErr_GivenExceptionMatches,3.2,
+function,PyErr_NewException,3.2,
+function,PyErr_NewExceptionWithDoc,3.2,
+function,PyErr_NoMemory,3.2,
+function,PyErr_NormalizeException,3.2,
+function,PyErr_Occurred,3.2,
+function,PyErr_Print,3.2,
+function,PyErr_PrintEx,3.2,
+function,PyErr_ProgramText,3.2,
+function,PyErr_ResourceWarning,3.6,
+function,PyErr_Restore,3.2,
+function,PyErr_SetExcFromWindowsErr,3.7,on Windows
+function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows
+function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows
+function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows
+function,PyErr_SetExcInfo,3.7,
+function,PyErr_SetFromErrno,3.2,
+function,PyErr_SetFromErrnoWithFilename,3.2,
+function,PyErr_SetFromErrnoWithFilenameObject,3.2,
+function,PyErr_SetFromErrnoWithFilenameObjects,3.7,
+function,PyErr_SetFromWindowsErr,3.7,on Windows
+function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows
+function,PyErr_SetImportError,3.7,
+function,PyErr_SetImportErrorSubclass,3.6,
+function,PyErr_SetInterrupt,3.2,
+function,PyErr_SetInterruptEx,3.10,
+function,PyErr_SetNone,3.2,
+function,PyErr_SetObject,3.2,
+function,PyErr_SetString,3.2,
+function,PyErr_SyntaxLocation,3.2,
+function,PyErr_SyntaxLocationEx,3.7,
+function,PyErr_WarnEx,3.2,
+function,PyErr_WarnExplicit,3.2,
+function,PyErr_WarnFormat,3.2,
+function,PyErr_WriteUnraisable,3.2,
+function,PyEval_AcquireLock,3.2,
+function,PyEval_AcquireThread,3.2,
+function,PyEval_CallFunction,3.2,
+function,PyEval_CallMethod,3.2,
+function,PyEval_CallObjectWithKeywords,3.2,
+function,PyEval_EvalCode,3.2,
+function,PyEval_EvalCodeEx,3.2,
+function,PyEval_EvalFrame,3.2,
+function,PyEval_EvalFrameEx,3.2,
+function,PyEval_GetBuiltins,3.2,
+function,PyEval_GetFrame,3.2,
+function,PyEval_GetFuncDesc,3.2,
+function,PyEval_GetFuncName,3.2,
+function,PyEval_GetGlobals,3.2,
+function,PyEval_GetLocals,3.2,
+function,PyEval_InitThreads,3.2,
+function,PyEval_ReleaseLock,3.2,
+function,PyEval_ReleaseThread,3.2,
+function,PyEval_RestoreThread,3.2,
+function,PyEval_SaveThread,3.2,
+function,PyEval_ThreadsInitialized,3.2,
+var,PyExc_ArithmeticError,3.2,
+var,PyExc_AssertionError,3.2,
+var,PyExc_AttributeError,3.2,
+var,PyExc_BaseException,3.2,
+var,PyExc_BlockingIOError,3.7,
+var,PyExc_BrokenPipeError,3.7,
+var,PyExc_BufferError,3.2,
+var,PyExc_BytesWarning,3.2,
+var,PyExc_ChildProcessError,3.7,
+var,PyExc_ConnectionAbortedError,3.7,
+var,PyExc_ConnectionError,3.7,
+var,PyExc_ConnectionRefusedError,3.7,
+var,PyExc_ConnectionResetError,3.7,
+var,PyExc_DeprecationWarning,3.2,
+var,PyExc_EOFError,3.2,
+var,PyExc_EncodingWarning,3.10,
+var,PyExc_EnvironmentError,3.2,
+var,PyExc_Exception,3.2,
+var,PyExc_FileExistsError,3.7,
+var,PyExc_FileNotFoundError,3.7,
+var,PyExc_FloatingPointError,3.2,
+var,PyExc_FutureWarning,3.2,
+var,PyExc_GeneratorExit,3.2,
+var,PyExc_IOError,3.2,
+var,PyExc_ImportError,3.2,
+var,PyExc_ImportWarning,3.2,
+var,PyExc_IndentationError,3.2,
+var,PyExc_IndexError,3.2,
+var,PyExc_InterruptedError,3.7,
+var,PyExc_IsADirectoryError,3.7,
+var,PyExc_KeyError,3.2,
+var,PyExc_KeyboardInterrupt,3.2,
+var,PyExc_LookupError,3.2,
+var,PyExc_MemoryError,3.2,
+var,PyExc_ModuleNotFoundError,3.6,
+var,PyExc_NameError,3.2,
+var,PyExc_NotADirectoryError,3.7,
+var,PyExc_NotImplementedError,3.2,
+var,PyExc_OSError,3.2,
+var,PyExc_OverflowError,3.2,
+var,PyExc_PendingDeprecationWarning,3.2,
+var,PyExc_PermissionError,3.7,
+var,PyExc_ProcessLookupError,3.7,
+var,PyExc_RecursionError,3.7,
+var,PyExc_ReferenceError,3.2,
+var,PyExc_ResourceWarning,3.7,
+var,PyExc_RuntimeError,3.2,
+var,PyExc_RuntimeWarning,3.2,
+var,PyExc_StopAsyncIteration,3.7,
+var,PyExc_StopIteration,3.2,
+var,PyExc_SyntaxError,3.2,
+var,PyExc_SyntaxWarning,3.2,
+var,PyExc_SystemError,3.2,
+var,PyExc_SystemExit,3.2,
+var,PyExc_TabError,3.2,
+var,PyExc_TimeoutError,3.7,
+var,PyExc_TypeError,3.2,
+var,PyExc_UnboundLocalError,3.2,
+var,PyExc_UnicodeDecodeError,3.2,
+var,PyExc_UnicodeEncodeError,3.2,
+var,PyExc_UnicodeError,3.2,
+var,PyExc_UnicodeTranslateError,3.2,
+var,PyExc_UnicodeWarning,3.2,
+var,PyExc_UserWarning,3.2,
+var,PyExc_ValueError,3.2,
+var,PyExc_Warning,3.2,
+var,PyExc_WindowsError,3.7,on Windows
+var,PyExc_ZeroDivisionError,3.2,
+function,PyExceptionClass_Name,3.8,
+function,PyException_GetCause,3.2,
+function,PyException_GetContext,3.2,
+function,PyException_GetTraceback,3.2,
+function,PyException_SetCause,3.2,
+function,PyException_SetContext,3.2,
+function,PyException_SetTraceback,3.2,
+function,PyFile_FromFd,3.2,
+function,PyFile_GetLine,3.2,
+function,PyFile_WriteObject,3.2,
+function,PyFile_WriteString,3.2,
+var,PyFilter_Type,3.2,
+function,PyFloat_AsDouble,3.2,
+function,PyFloat_FromDouble,3.2,
+function,PyFloat_FromString,3.2,
+function,PyFloat_GetInfo,3.2,
+function,PyFloat_GetMax,3.2,
+function,PyFloat_GetMin,3.2,
+var,PyFloat_Type,3.2,
+type,PyFrameObject,3.2,
+function,PyFrame_GetCode,3.10,
+function,PyFrame_GetLineNumber,3.10,
+function,PyFrozenSet_New,3.2,
+var,PyFrozenSet_Type,3.2,
+function,PyGC_Collect,3.2,
+function,PyGC_Disable,3.10,
+function,PyGC_Enable,3.10,
+function,PyGC_IsEnabled,3.10,
+function,PyGILState_Ensure,3.2,
+function,PyGILState_GetThisThreadState,3.2,
+function,PyGILState_Release,3.2,
+type,PyGILState_STATE,3.2,
+type,PyGetSetDef,3.2,
+var,PyGetSetDescr_Type,3.2,
+function,PyImport_AddModule,3.2,
+function,PyImport_AddModuleObject,3.7,
+function,PyImport_AppendInittab,3.2,
+function,PyImport_ExecCodeModule,3.2,
+function,PyImport_ExecCodeModuleEx,3.2,
+function,PyImport_ExecCodeModuleObject,3.7,
+function,PyImport_ExecCodeModuleWithPathnames,3.2,
+function,PyImport_GetImporter,3.2,
+function,PyImport_GetMagicNumber,3.2,
+function,PyImport_GetMagicTag,3.2,
+function,PyImport_GetModule,3.8,
+function,PyImport_GetModuleDict,3.2,
+function,PyImport_Import,3.2,
+function,PyImport_ImportFrozenModule,3.2,
+function,PyImport_ImportFrozenModuleObject,3.7,
+function,PyImport_ImportModule,3.2,
+function,PyImport_ImportModuleLevel,3.2,
+function,PyImport_ImportModuleLevelObject,3.7,
+function,PyImport_ImportModuleNoBlock,3.2,
+function,PyImport_ReloadModule,3.2,
+function,PyIndex_Check,3.8,
+type,PyInterpreterState,3.2,
+function,PyInterpreterState_Clear,3.2,
+function,PyInterpreterState_Delete,3.2,
+function,PyInterpreterState_Get,3.9,
+function,PyInterpreterState_GetDict,3.8,
+function,PyInterpreterState_GetID,3.7,
+function,PyInterpreterState_New,3.2,
+function,PyIter_Check,3.8,
+function,PyIter_Next,3.2,
+function,PyIter_Send,3.10,
+var,PyListIter_Type,3.2,
+var,PyListRevIter_Type,3.2,
+function,PyList_Append,3.2,
+function,PyList_AsTuple,3.2,
+function,PyList_GetItem,3.2,
+function,PyList_GetSlice,3.2,
+function,PyList_Insert,3.2,
+function,PyList_New,3.2,
+function,PyList_Reverse,3.2,
+function,PyList_SetItem,3.2,
+function,PyList_SetSlice,3.2,
+function,PyList_Size,3.2,
+function,PyList_Sort,3.2,
+var,PyList_Type,3.2,
+type,PyLongObject,3.2,
+var,PyLongRangeIter_Type,3.2,
+function,PyLong_AsDouble,3.2,
+function,PyLong_AsLong,3.2,
+function,PyLong_AsLongAndOverflow,3.2,
+function,PyLong_AsLongLong,3.2,
+function,PyLong_AsLongLongAndOverflow,3.2,
+function,PyLong_AsSize_t,3.2,
+function,PyLong_AsSsize_t,3.2,
+function,PyLong_AsUnsignedLong,3.2,
+function,PyLong_AsUnsignedLongLong,3.2,
+function,PyLong_AsUnsignedLongLongMask,3.2,
+function,PyLong_AsUnsignedLongMask,3.2,
+function,PyLong_AsVoidPtr,3.2,
+function,PyLong_FromDouble,3.2,
+function,PyLong_FromLong,3.2,
+function,PyLong_FromLongLong,3.2,
+function,PyLong_FromSize_t,3.2,
+function,PyLong_FromSsize_t,3.2,
+function,PyLong_FromString,3.2,
+function,PyLong_FromUnsignedLong,3.2,
+function,PyLong_FromUnsignedLongLong,3.2,
+function,PyLong_FromVoidPtr,3.2,
+function,PyLong_GetInfo,3.2,
+var,PyLong_Type,3.2,
+var,PyMap_Type,3.2,
+function,PyMapping_Check,3.2,
+function,PyMapping_GetItemString,3.2,
+function,PyMapping_HasKey,3.2,
+function,PyMapping_HasKeyString,3.2,
+function,PyMapping_Items,3.2,
+function,PyMapping_Keys,3.2,
+function,PyMapping_Length,3.2,
+function,PyMapping_SetItemString,3.2,
+function,PyMapping_Size,3.2,
+function,PyMapping_Values,3.2,
+function,PyMem_Calloc,3.7,
+function,PyMem_Free,3.2,
+function,PyMem_Malloc,3.2,
+function,PyMem_Realloc,3.2,
+type,PyMemberDef,3.2,
+var,PyMemberDescr_Type,3.2,
+function,PyMemoryView_FromMemory,3.7,
+function,PyMemoryView_FromObject,3.2,
+function,PyMemoryView_GetContiguous,3.2,
+var,PyMemoryView_Type,3.2,
+type,PyMethodDef,3.2,
+var,PyMethodDescr_Type,3.2,
+type,PyModuleDef,3.2,
+type,PyModuleDef_Base,3.2,
+function,PyModuleDef_Init,3.5,
+var,PyModuleDef_Type,3.5,
+function,PyModule_AddFunctions,3.7,
+function,PyModule_AddIntConstant,3.2,
+function,PyModule_AddObject,3.2,
+function,PyModule_AddObjectRef,3.10,
+function,PyModule_AddStringConstant,3.2,
+function,PyModule_AddType,3.10,
+function,PyModule_Create2,3.2,
+function,PyModule_ExecDef,3.7,
+function,PyModule_FromDefAndSpec2,3.7,
+function,PyModule_GetDef,3.2,
+function,PyModule_GetDict,3.2,
+function,PyModule_GetFilename,3.2,
+function,PyModule_GetFilenameObject,3.2,
+function,PyModule_GetName,3.2,
+function,PyModule_GetNameObject,3.7,
+function,PyModule_GetState,3.2,
+function,PyModule_New,3.2,
+function,PyModule_NewObject,3.7,
+function,PyModule_SetDocString,3.7,
+var,PyModule_Type,3.2,
+function,PyNumber_Absolute,3.2,
+function,PyNumber_Add,3.2,
+function,PyNumber_And,3.2,
+function,PyNumber_AsSsize_t,3.2,
+function,PyNumber_Check,3.2,
+function,PyNumber_Divmod,3.2,
+function,PyNumber_Float,3.2,
+function,PyNumber_FloorDivide,3.2,
+function,PyNumber_InPlaceAdd,3.2,
+function,PyNumber_InPlaceAnd,3.2,
+function,PyNumber_InPlaceFloorDivide,3.2,
+function,PyNumber_InPlaceLshift,3.2,
+function,PyNumber_InPlaceMatrixMultiply,3.7,
+function,PyNumber_InPlaceMultiply,3.2,
+function,PyNumber_InPlaceOr,3.2,
+function,PyNumber_InPlacePower,3.2,
+function,PyNumber_InPlaceRemainder,3.2,
+function,PyNumber_InPlaceRshift,3.2,
+function,PyNumber_InPlaceSubtract,3.2,
+function,PyNumber_InPlaceTrueDivide,3.2,
+function,PyNumber_InPlaceXor,3.2,
+function,PyNumber_Index,3.2,
+function,PyNumber_Invert,3.2,
+function,PyNumber_Long,3.2,
+function,PyNumber_Lshift,3.2,
+function,PyNumber_MatrixMultiply,3.7,
+function,PyNumber_Multiply,3.2,
+function,PyNumber_Negative,3.2,
+function,PyNumber_Or,3.2,
+function,PyNumber_Positive,3.2,
+function,PyNumber_Power,3.2,
+function,PyNumber_Remainder,3.2,
+function,PyNumber_Rshift,3.2,
+function,PyNumber_Subtract,3.2,
+function,PyNumber_ToBase,3.2,
+function,PyNumber_TrueDivide,3.2,
+function,PyNumber_Xor,3.2,
+function,PyOS_AfterFork,3.2,on platforms with fork()
+function,PyOS_AfterFork_Child,3.7,on platforms with fork()
+function,PyOS_AfterFork_Parent,3.7,on platforms with fork()
+function,PyOS_BeforeFork,3.7,on platforms with fork()
+function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK
+function,PyOS_FSPath,3.6,
+var,PyOS_InputHook,3.2,
+function,PyOS_InterruptOccurred,3.2,
+function,PyOS_double_to_string,3.2,
+function,PyOS_getsig,3.2,
+function,PyOS_mystricmp,3.2,
+function,PyOS_mystrnicmp,3.2,
+function,PyOS_setsig,3.2,
+type,PyOS_sighandler_t,3.2,
+function,PyOS_snprintf,3.2,
+function,PyOS_string_to_double,3.2,
+function,PyOS_strtol,3.2,
+function,PyOS_strtoul,3.2,
+function,PyOS_vsnprintf,3.2,
+type,PyObject,3.2,
+function,PyObject_ASCII,3.2,
+function,PyObject_AsCharBuffer,3.2,
+function,PyObject_AsFileDescriptor,3.2,
+function,PyObject_AsReadBuffer,3.2,
+function,PyObject_AsWriteBuffer,3.2,
+function,PyObject_Bytes,3.2,
+function,PyObject_Call,3.2,
+function,PyObject_CallFunction,3.2,
+function,PyObject_CallFunctionObjArgs,3.2,
+function,PyObject_CallMethod,3.2,
+function,PyObject_CallMethodObjArgs,3.2,
+function,PyObject_CallNoArgs,3.10,
+function,PyObject_CallObject,3.2,
+function,PyObject_Calloc,3.7,
+function,PyObject_CheckReadBuffer,3.2,
+function,PyObject_ClearWeakRefs,3.2,
+function,PyObject_DelItem,3.2,
+function,PyObject_DelItemString,3.2,
+function,PyObject_Dir,3.2,
+function,PyObject_Format,3.2,
+function,PyObject_Free,3.2,
+function,PyObject_GC_Del,3.2,
+function,PyObject_GC_IsFinalized,3.9,
+function,PyObject_GC_IsTracked,3.9,
+function,PyObject_GC_Track,3.2,
+function,PyObject_GC_UnTrack,3.2,
+function,PyObject_GenericGetAttr,3.2,
+function,PyObject_GenericGetDict,3.10,
+function,PyObject_GenericSetAttr,3.2,
+function,PyObject_GenericSetDict,3.7,
+function,PyObject_GetAIter,3.10,
+function,PyObject_GetAttr,3.2,
+function,PyObject_GetAttrString,3.2,
+function,PyObject_GetItem,3.2,
+function,PyObject_GetIter,3.2,
+function,PyObject_HasAttr,3.2,
+function,PyObject_HasAttrString,3.2,
+function,PyObject_Hash,3.2,
+function,PyObject_HashNotImplemented,3.2,
+function,PyObject_Init,3.2,
+function,PyObject_InitVar,3.2,
+function,PyObject_IsInstance,3.2,
+function,PyObject_IsSubclass,3.2,
+function,PyObject_IsTrue,3.2,
+function,PyObject_Length,3.2,
+function,PyObject_Malloc,3.2,
+function,PyObject_Not,3.2,
+function,PyObject_Realloc,3.2,
+function,PyObject_Repr,3.2,
+function,PyObject_RichCompare,3.2,
+function,PyObject_RichCompareBool,3.2,
+function,PyObject_SelfIter,3.2,
+function,PyObject_SetAttr,3.2,
+function,PyObject_SetAttrString,3.2,
+function,PyObject_SetItem,3.2,
+function,PyObject_Size,3.2,
+function,PyObject_Str,3.2,
+function,PyObject_Type,3.2,
+var,PyProperty_Type,3.2,
+var,PyRangeIter_Type,3.2,
+var,PyRange_Type,3.2,
+var,PyReversed_Type,3.2,
+function,PySeqIter_New,3.2,
+var,PySeqIter_Type,3.2,
+function,PySequence_Check,3.2,
+function,PySequence_Concat,3.2,
+function,PySequence_Contains,3.2,
+function,PySequence_Count,3.2,
+function,PySequence_DelItem,3.2,
+function,PySequence_DelSlice,3.2,
+function,PySequence_Fast,3.2,
+function,PySequence_GetItem,3.2,
+function,PySequence_GetSlice,3.2,
+function,PySequence_In,3.2,
+function,PySequence_InPlaceConcat,3.2,
+function,PySequence_InPlaceRepeat,3.2,
+function,PySequence_Index,3.2,
+function,PySequence_Length,3.2,
+function,PySequence_List,3.2,
+function,PySequence_Repeat,3.2,
+function,PySequence_SetItem,3.2,
+function,PySequence_SetSlice,3.2,
+function,PySequence_Size,3.2,
+function,PySequence_Tuple,3.2,
+var,PySetIter_Type,3.2,
+function,PySet_Add,3.2,
+function,PySet_Clear,3.2,
+function,PySet_Contains,3.2,
+function,PySet_Discard,3.2,
+function,PySet_New,3.2,
+function,PySet_Pop,3.2,
+function,PySet_Size,3.2,
+var,PySet_Type,3.2,
+function,PySlice_AdjustIndices,3.7,
+function,PySlice_GetIndices,3.2,
+function,PySlice_GetIndicesEx,3.2,
+function,PySlice_New,3.2,
+var,PySlice_Type,3.2,
+function,PySlice_Unpack,3.7,
+function,PyState_AddModule,3.3,
+function,PyState_FindModule,3.2,
+function,PyState_RemoveModule,3.3,
+type,PyStructSequence_Desc,3.2,
+type,PyStructSequence_Field,3.2,
+function,PyStructSequence_GetItem,3.2,
+function,PyStructSequence_New,3.2,
+function,PyStructSequence_NewType,3.2,
+function,PyStructSequence_SetItem,3.2,
+var,PySuper_Type,3.2,
+function,PySys_AddWarnOption,3.2,
+function,PySys_AddWarnOptionUnicode,3.2,
+function,PySys_AddXOption,3.7,
+function,PySys_FormatStderr,3.2,
+function,PySys_FormatStdout,3.2,
+function,PySys_GetObject,3.2,
+function,PySys_GetXOptions,3.7,
+function,PySys_HasWarnOptions,3.2,
+function,PySys_ResetWarnOptions,3.2,
+function,PySys_SetArgv,3.2,
+function,PySys_SetArgvEx,3.2,
+function,PySys_SetObject,3.2,
+function,PySys_SetPath,3.2,
+function,PySys_WriteStderr,3.2,
+function,PySys_WriteStdout,3.2,
+type,PyThreadState,3.2,
+function,PyThreadState_Clear,3.2,
+function,PyThreadState_Delete,3.2,
+function,PyThreadState_Get,3.2,
+function,PyThreadState_GetDict,3.2,
+function,PyThreadState_GetFrame,3.10,
+function,PyThreadState_GetID,3.10,
+function,PyThreadState_GetInterpreter,3.10,
+function,PyThreadState_New,3.2,
+function,PyThreadState_SetAsyncExc,3.2,
+function,PyThreadState_Swap,3.2,
+function,PyThread_GetInfo,3.3,
+function,PyThread_ReInitTLS,3.2,
+function,PyThread_acquire_lock,3.2,
+function,PyThread_acquire_lock_timed,3.2,
+function,PyThread_allocate_lock,3.2,
+function,PyThread_create_key,3.2,
+function,PyThread_delete_key,3.2,
+function,PyThread_delete_key_value,3.2,
+function,PyThread_exit_thread,3.2,
+function,PyThread_free_lock,3.2,
+function,PyThread_get_key_value,3.2,
+function,PyThread_get_stacksize,3.2,
+function,PyThread_get_thread_ident,3.2,
+function,PyThread_get_thread_native_id,3.2,
+function,PyThread_init_thread,3.2,
+function,PyThread_release_lock,3.2,
+function,PyThread_set_key_value,3.2,
+function,PyThread_set_stacksize,3.2,
+function,PyThread_start_new_thread,3.2,
+function,PyThread_tss_alloc,3.7,
+function,PyThread_tss_create,3.7,
+function,PyThread_tss_delete,3.7,
+function,PyThread_tss_free,3.7,
+function,PyThread_tss_get,3.7,
+function,PyThread_tss_is_created,3.7,
+function,PyThread_tss_set,3.7,
+function,PyTraceBack_Here,3.2,
+function,PyTraceBack_Print,3.2,
+var,PyTraceBack_Type,3.2,
+var,PyTupleIter_Type,3.2,
+function,PyTuple_GetItem,3.2,
+function,PyTuple_GetSlice,3.2,
+function,PyTuple_New,3.2,
+function,PyTuple_Pack,3.2,
+function,PyTuple_SetItem,3.2,
+function,PyTuple_Size,3.2,
+var,PyTuple_Type,3.2,
+type,PyTypeObject,3.2,
+function,PyType_ClearCache,3.2,
+function,PyType_FromModuleAndSpec,3.10,
+function,PyType_FromSpec,3.2,
+function,PyType_FromSpecWithBases,3.3,
+function,PyType_GenericAlloc,3.2,
+function,PyType_GenericNew,3.2,
+function,PyType_GetFlags,3.2,
+function,PyType_GetModule,3.10,
+function,PyType_GetModuleState,3.10,
+function,PyType_GetSlot,3.4,
+function,PyType_IsSubtype,3.2,
+function,PyType_Modified,3.2,
+function,PyType_Ready,3.2,
+type,PyType_Slot,3.2,
+type,PyType_Spec,3.2,
+var,PyType_Type,3.2,
+function,PyUnicodeDecodeError_Create,3.2,
+function,PyUnicodeDecodeError_GetEncoding,3.2,
+function,PyUnicodeDecodeError_GetEnd,3.2,
+function,PyUnicodeDecodeError_GetObject,3.2,
+function,PyUnicodeDecodeError_GetReason,3.2,
+function,PyUnicodeDecodeError_GetStart,3.2,
+function,PyUnicodeDecodeError_SetEnd,3.2,
+function,PyUnicodeDecodeError_SetReason,3.2,
+function,PyUnicodeDecodeError_SetStart,3.2,
+function,PyUnicodeEncodeError_GetEncoding,3.2,
+function,PyUnicodeEncodeError_GetEnd,3.2,
+function,PyUnicodeEncodeError_GetObject,3.2,
+function,PyUnicodeEncodeError_GetReason,3.2,
+function,PyUnicodeEncodeError_GetStart,3.2,
+function,PyUnicodeEncodeError_SetEnd,3.2,
+function,PyUnicodeEncodeError_SetReason,3.2,
+function,PyUnicodeEncodeError_SetStart,3.2,
+var,PyUnicodeIter_Type,3.2,
+function,PyUnicodeTranslateError_GetEnd,3.2,
+function,PyUnicodeTranslateError_GetObject,3.2,
+function,PyUnicodeTranslateError_GetReason,3.2,
+function,PyUnicodeTranslateError_GetStart,3.2,
+function,PyUnicodeTranslateError_SetEnd,3.2,
+function,PyUnicodeTranslateError_SetReason,3.2,
+function,PyUnicodeTranslateError_SetStart,3.2,
+function,PyUnicode_Append,3.2,
+function,PyUnicode_AppendAndDel,3.2,
+function,PyUnicode_AsASCIIString,3.2,
+function,PyUnicode_AsCharmapString,3.2,
+function,PyUnicode_AsDecodedObject,3.2,
+function,PyUnicode_AsDecodedUnicode,3.2,
+function,PyUnicode_AsEncodedObject,3.2,
+function,PyUnicode_AsEncodedString,3.2,
+function,PyUnicode_AsEncodedUnicode,3.2,
+function,PyUnicode_AsLatin1String,3.2,
+function,PyUnicode_AsMBCSString,3.7,on Windows
+function,PyUnicode_AsRawUnicodeEscapeString,3.2,
+function,PyUnicode_AsUCS4,3.7,
+function,PyUnicode_AsUCS4Copy,3.7,
+function,PyUnicode_AsUTF16String,3.2,
+function,PyUnicode_AsUTF32String,3.2,
+function,PyUnicode_AsUTF8AndSize,3.10,
+function,PyUnicode_AsUTF8String,3.2,
+function,PyUnicode_AsUnicodeEscapeString,3.2,
+function,PyUnicode_AsWideChar,3.2,
+function,PyUnicode_AsWideCharString,3.7,
+function,PyUnicode_BuildEncodingMap,3.2,
+function,PyUnicode_Compare,3.2,
+function,PyUnicode_CompareWithASCIIString,3.2,
+function,PyUnicode_Concat,3.2,
+function,PyUnicode_Contains,3.2,
+function,PyUnicode_Count,3.2,
+function,PyUnicode_Decode,3.2,
+function,PyUnicode_DecodeASCII,3.2,
+function,PyUnicode_DecodeCharmap,3.2,
+function,PyUnicode_DecodeCodePageStateful,3.7,on Windows
+function,PyUnicode_DecodeFSDefault,3.2,
+function,PyUnicode_DecodeFSDefaultAndSize,3.2,
+function,PyUnicode_DecodeLatin1,3.2,
+function,PyUnicode_DecodeLocale,3.7,
+function,PyUnicode_DecodeLocaleAndSize,3.7,
+function,PyUnicode_DecodeMBCS,3.7,on Windows
+function,PyUnicode_DecodeMBCSStateful,3.7,on Windows
+function,PyUnicode_DecodeRawUnicodeEscape,3.2,
+function,PyUnicode_DecodeUTF16,3.2,
+function,PyUnicode_DecodeUTF16Stateful,3.2,
+function,PyUnicode_DecodeUTF32,3.2,
+function,PyUnicode_DecodeUTF32Stateful,3.2,
+function,PyUnicode_DecodeUTF7,3.2,
+function,PyUnicode_DecodeUTF7Stateful,3.2,
+function,PyUnicode_DecodeUTF8,3.2,
+function,PyUnicode_DecodeUTF8Stateful,3.2,
+function,PyUnicode_DecodeUnicodeEscape,3.2,
+function,PyUnicode_EncodeCodePage,3.7,on Windows
+function,PyUnicode_EncodeFSDefault,3.2,
+function,PyUnicode_EncodeLocale,3.7,
+function,PyUnicode_FSConverter,3.2,
+function,PyUnicode_FSDecoder,3.2,
+function,PyUnicode_Find,3.2,
+function,PyUnicode_FindChar,3.7,
+function,PyUnicode_Format,3.2,
+function,PyUnicode_FromEncodedObject,3.2,
+function,PyUnicode_FromFormat,3.2,
+function,PyUnicode_FromFormatV,3.2,
+function,PyUnicode_FromObject,3.2,
+function,PyUnicode_FromOrdinal,3.2,
+function,PyUnicode_FromString,3.2,
+function,PyUnicode_FromStringAndSize,3.2,
+function,PyUnicode_FromWideChar,3.2,
+function,PyUnicode_GetDefaultEncoding,3.2,
+function,PyUnicode_GetLength,3.7,
+function,PyUnicode_GetSize,3.2,
+function,PyUnicode_InternFromString,3.2,
+function,PyUnicode_InternImmortal,3.2,
+function,PyUnicode_InternInPlace,3.2,
+function,PyUnicode_IsIdentifier,3.2,
+function,PyUnicode_Join,3.2,
+function,PyUnicode_Partition,3.2,
+function,PyUnicode_RPartition,3.2,
+function,PyUnicode_RSplit,3.2,
+function,PyUnicode_ReadChar,3.7,
+function,PyUnicode_Replace,3.2,
+function,PyUnicode_Resize,3.2,
+function,PyUnicode_RichCompare,3.2,
+function,PyUnicode_Split,3.2,
+function,PyUnicode_Splitlines,3.2,
+function,PyUnicode_Substring,3.7,
+function,PyUnicode_Tailmatch,3.2,
+function,PyUnicode_Translate,3.2,
+var,PyUnicode_Type,3.2,
+function,PyUnicode_WriteChar,3.7,
+type,PyVarObject,3.2,
+type,PyWeakReference,3.2,
+function,PyWeakref_GetObject,3.2,
+function,PyWeakref_NewProxy,3.2,
+function,PyWeakref_NewRef,3.2,
+var,PyWrapperDescr_Type,3.2,
+function,PyWrapper_New,3.2,
+var,PyZip_Type,3.2,
+function,Py_AddPendingCall,3.2,
+function,Py_AtExit,3.2,
+macro,Py_BEGIN_ALLOW_THREADS,3.2,
+macro,Py_BLOCK_THREADS,3.2,
+function,Py_BuildValue,3.2,
+function,Py_BytesMain,3.8,
+function,Py_CompileString,3.2,
+function,Py_DecRef,3.2,
+function,Py_DecodeLocale,3.7,
+macro,Py_END_ALLOW_THREADS,3.2,
+function,Py_EncodeLocale,3.7,
+function,Py_EndInterpreter,3.2,
+function,Py_EnterRecursiveCall,3.9,
+function,Py_Exit,3.2,
+function,Py_FatalError,3.2,
+var,Py_FileSystemDefaultEncodeErrors,3.10,
+var,Py_FileSystemDefaultEncoding,3.2,
+function,Py_Finalize,3.2,
+function,Py_FinalizeEx,3.6,
+function,Py_GenericAlias,3.9,
+var,Py_GenericAliasType,3.9,
+function,Py_GetBuildInfo,3.2,
+function,Py_GetCompiler,3.2,
+function,Py_GetCopyright,3.2,
+function,Py_GetExecPrefix,3.2,
+function,Py_GetPath,3.2,
+function,Py_GetPlatform,3.2,
+function,Py_GetPrefix,3.2,
+function,Py_GetProgramFullPath,3.2,
+function,Py_GetProgramName,3.2,
+function,Py_GetPythonHome,3.2,
+function,Py_GetRecursionLimit,3.2,
+function,Py_GetVersion,3.2,
+var,Py_HasFileSystemDefaultEncoding,3.2,
+function,Py_IncRef,3.2,
+function,Py_Initialize,3.2,
+function,Py_InitializeEx,3.2,
+function,Py_Is,3.10,
+function,Py_IsFalse,3.10,
+function,Py_IsInitialized,3.2,
+function,Py_IsNone,3.10,
+function,Py_IsTrue,3.10,
+function,Py_LeaveRecursiveCall,3.9,
+function,Py_Main,3.2,
+function,Py_MakePendingCalls,3.2,
+function,Py_NewInterpreter,3.2,
+function,Py_NewRef,3.10,
+function,Py_ReprEnter,3.2,
+function,Py_ReprLeave,3.2,
+function,Py_SetPath,3.7,
+function,Py_SetProgramName,3.2,
+function,Py_SetPythonHome,3.2,
+function,Py_SetRecursionLimit,3.2,
+type,Py_UCS4,3.2,
+macro,Py_UNBLOCK_THREADS,3.2,
+var,Py_UTF8Mode,3.8,
+function,Py_VaBuildValue,3.2,
+function,Py_XNewRef,3.10,
+type,Py_intptr_t,3.2,
+type,Py_ssize_t,3.2,
+type,Py_uintptr_t,3.2,
+type,allocfunc,3.2,
+type,binaryfunc,3.2,
+type,descrgetfunc,3.2,
+type,descrsetfunc,3.2,
+type,destructor,3.2,
+type,getattrfunc,3.2,
+type,getattrofunc,3.2,
+type,getiterfunc,3.2,
+type,getter,3.2,
+type,hashfunc,3.2,
+type,initproc,3.2,
+type,inquiry,3.2,
+type,iternextfunc,3.2,
+type,lenfunc,3.2,
+type,newfunc,3.2,
+type,objobjargproc,3.2,
+type,objobjproc,3.2,
+type,reprfunc,3.2,
+type,richcmpfunc,3.2,
+type,setattrfunc,3.2,
+type,setattrofunc,3.2,
+type,setter,3.2,
+type,ssizeargfunc,3.2,
+type,ssizeobjargproc,3.2,
+type,ssizessizeargfunc,3.2,
+type,ssizessizeobjargproc,3.2,
+type,symtable,3.2,
+type,ternaryfunc,3.2,
+type,traverseproc,3.2,
+type,unaryfunc,3.2,
+type,visitproc,3.2,
diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst
index 02379946244d84..136cf4e77b1543 100644
--- a/Doc/distributing/index.rst
+++ b/Doc/distributing/index.rst
@@ -31,7 +31,7 @@ installing other Python projects, refer to the
Key terms
=========
-* the `Python Packaging Index `__ is a public
+* the `Python Package Index `__ is a public
repository of open source licensed packages made available for use by
other Python users
* the `Python Packaging Authority
@@ -101,7 +101,7 @@ by invoking the ``pip`` module at the command line::
.. note::
- For POSIX users (including Mac OS X and Linux users), these instructions
+ For POSIX users (including macOS and Linux users), these instructions
assume the use of a :term:`virtual environment`.
For Windows users, these instructions assume that the option to
@@ -127,15 +127,15 @@ involved in creating and publishing a project:
* `Project structure`_
* `Building and packaging the project`_
-* `Uploading the project to the Python Packaging Index`_
+* `Uploading the project to the Python Package Index`_
* `The .pypirc file`_
.. _Project structure: \
- https://packaging.python.org/tutorials/distributing-packages/
+ https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects
.. _Building and packaging the project: \
- https://packaging.python.org/tutorials/distributing-packages/#packaging-your-project
-.. _Uploading the project to the Python Packaging Index: \
- https://packaging.python.org/tutorials/distributing-packages/#uploading-your-project-to-pypi
+ https://packaging.python.org/tutorials/packaging-projects/#creating-the-package-files
+.. _Uploading the project to the Python Package Index: \
+ https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives
.. _The .pypirc file: \
https://packaging.python.org/specifications/pypirc/
@@ -150,7 +150,7 @@ These are quick answers or links for some common tasks.
This isn't an easy topic, but here are a few tips:
-* check the Python Packaging Index to see if the name is already in use
+* check the Python Package Index to see if the name is already in use
* check popular hosting sites like GitHub, Bitbucket, etc to see if there
is already a project with that name
* check what comes up in a web search for the name you're considering
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index e4437f4106b519..5a13acf1485e18 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -11,7 +11,7 @@ API Reference
and other APIs, makes the API consistent across different Python versions,
and is hence recommended over using ``distutils`` directly.
-.. _New and changed setup.py arguments in setuptools: https://setuptools.readthedocs.io/en/latest/setuptools.html#new-and-changed-setup-keywords
+.. _New and changed setup.py arguments in setuptools: https://web.archive.org/web/20210614192516/https://setuptools.pypa.io/en/stable/userguide/keywords.html
.. include:: ./_setuptools_disclaimer.rst
@@ -373,7 +373,7 @@ This module provides the following functions.
compiler object under Unix---if you supply a value for *compiler*, *plat* is
ignored.
- .. % Is the posix/nt only thing still true? Mac OS X seems to work, and
+ .. % Is the posix/nt only thing still true? macOS seems to work, and
.. % returns a UnixCCompiler instance. How to document this... hmm.
@@ -1119,11 +1119,11 @@ other utility module.
For non-POSIX platforms, currently just returns ``sys.platform``.
- For Mac OS X systems the OS version reflects the minimal version on which
+ For macOS systems the OS version reflects the minimal version on which
binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET``
during the build of Python), not the OS version of the current system.
- For universal binary builds on Mac OS X the architecture value reflects
+ For universal binary builds on macOS the architecture value reflects
the universal binary status instead of the architecture of the current
processor. For 32-bit universal binaries the architecture is ``fat``,
for 64-bit universal binaries the architecture is ``fat64``, and
@@ -1132,7 +1132,7 @@ other utility module.
a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for
a universal build with the i386 and x86_64 architectures
- Examples of returned values on Mac OS X:
+ Examples of returned values on macOS:
* ``macosx-10.3-ppc``
diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst
index 0600663d00e9dc..7b1e22f824e8ce 100644
--- a/Doc/distutils/sourcedist.rst
+++ b/Doc/distutils/sourcedist.rst
@@ -23,25 +23,25 @@ option, for example::
to create a gzipped tarball and a zip file. The available formats are:
-+-----------+-------------------------+---------+
-| Format | Description | Notes |
-+===========+=========================+=========+
-| ``zip`` | zip file (:file:`.zip`) | (1),(3) |
-+-----------+-------------------------+---------+
-| ``gztar`` | gzip'ed tar file | \(2) |
-| | (:file:`.tar.gz`) | |
-+-----------+-------------------------+---------+
-| ``bztar`` | bzip2'ed tar file | |
-| | (:file:`.tar.bz2`) | |
-+-----------+-------------------------+---------+
-| ``xztar`` | xz'ed tar file | |
-| | (:file:`.tar.xz`) | |
-+-----------+-------------------------+---------+
-| ``ztar`` | compressed tar file | \(4) |
-| | (:file:`.tar.Z`) | |
-+-----------+-------------------------+---------+
-| ``tar`` | tar file (:file:`.tar`) | |
-+-----------+-------------------------+---------+
++-----------+-------------------------+-------------+
+| Format | Description | Notes |
++===========+=========================+=============+
+| ``zip`` | zip file (:file:`.zip`) | (1),(3) |
++-----------+-------------------------+-------------+
+| ``gztar`` | gzip'ed tar file | \(2) |
+| | (:file:`.tar.gz`) | |
++-----------+-------------------------+-------------+
+| ``bztar`` | bzip2'ed tar file | \(5) |
+| | (:file:`.tar.bz2`) | |
++-----------+-------------------------+-------------+
+| ``xztar`` | xz'ed tar file | \(5) |
+| | (:file:`.tar.xz`) | |
++-----------+-------------------------+-------------+
+| ``ztar`` | compressed tar file | (4),(5) |
+| | (:file:`.tar.Z`) | |
++-----------+-------------------------+-------------+
+| ``tar`` | tar file (:file:`.tar`) | \(5) |
++-----------+-------------------------+-------------+
.. versionchanged:: 3.5
Added support for the ``xztar`` format.
@@ -61,6 +61,9 @@ Notes:
(4)
requires the :program:`compress` program. Notice that this format is now
pending for deprecation and will be removed in the future versions of Python.
+(5)
+ deprecated by `PEP 527 `_;
+ `PyPI `_ only accepts ``.zip`` and ``.tar.gz`` files.
When using any ``tar`` format (``gztar``, ``bztar``, ``xztar``, ``ztar`` or
``tar``), under Unix you can specify the ``owner`` and ``group`` names
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index 561d1c616cc10e..2e3362b834e6fb 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -127,13 +127,11 @@ Intermezzo: Errors and Exceptions
An important convention throughout the Python interpreter is the following: when
a function fails, it should set an exception condition and return an error value
-(usually a ``NULL`` pointer). Exceptions are stored in a static global variable
-inside the interpreter; if this variable is ``NULL`` no exception has occurred. A
-second global variable stores the "associated value" of the exception (the
-second argument to :keyword:`raise`). A third variable contains the stack
-traceback in case the error originated in Python code. These three variables
-are the C equivalents of the result in Python of :meth:`sys.exc_info` (see the
-section on module :mod:`sys` in the Python Library Reference). It is important
+(usually ``-1`` or a ``NULL`` pointer). Exception information is stored in
+three members of the interpreter's thread state. These are ``NULL`` if
+there is no exception. Otherwise they are the C equivalents of the members
+of the Python tuple returned by :meth:`sys.exc_info`. These are the
+exception type, exception instance, and a traceback object. It is important
to know about them to understand how errors are passed around.
The Python API defines a number of functions to set various types of exceptions.
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index 6e17897ed2c805..f75bee9e6f2a2b 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -73,7 +73,19 @@ function::
newdatatype_dealloc(newdatatypeobject *obj)
{
free(obj->obj_UnderlyingDatatypePtr);
- Py_TYPE(obj)->tp_free(obj);
+ Py_TYPE(obj)->tp_free((PyObject *)obj);
+ }
+
+If your type supports garbage collection, the destructor should call
+:c:func:`PyObject_GC_UnTrack` before clearing any member fields::
+
+ static void
+ newdatatype_dealloc(newdatatypeobject *obj)
+ {
+ PyObject_GC_UnTrack(obj);
+ Py_CLEAR(obj->other_obj);
+ ...
+ Py_TYPE(obj)->tp_free((PyObject *)obj);
}
.. index::
@@ -381,7 +393,7 @@ analogous to the :ref:`rich comparison methods `, like
:c:func:`PyObject_RichCompareBool`.
This function is called with two Python objects and the operator as arguments,
-where the operator is one of ``Py_EQ``, ``Py_NE``, ``Py_LE``, ``Py_GT``,
+where the operator is one of ``Py_EQ``, ``Py_NE``, ``Py_LE``, ``Py_GE``,
``Py_LT`` or ``Py_GT``. It should compare the two objects with respect to the
specified operator and return ``Py_True`` or ``Py_False`` if the comparison is
successful, ``Py_NotImplemented`` to indicate that comparison is not
diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst
index 530e2c4d35f848..34c25d1f6f199c 100644
--- a/Doc/extending/newtypes_tutorial.rst
+++ b/Doc/extending/newtypes_tutorial.rst
@@ -67,8 +67,8 @@ The first bit is::
This is what a Custom object will contain. ``PyObject_HEAD`` is mandatory
at the start of each object struct and defines a field called ``ob_base``
of type :c:type:`PyObject`, containing a pointer to a type object and a
-reference count (these can be accessed using the macros :c:macro:`Py_REFCNT`
-and :c:macro:`Py_TYPE` respectively). The reason for the macro is to
+reference count (these can be accessed using the macros :c:macro:`Py_TYPE`
+and :c:macro:`Py_REFCNT` respectively). The reason for the macro is to
abstract away the layout and to enable additional fields in :ref:`debug builds
`.
@@ -90,7 +90,7 @@ The second bit is the definition of the type object. ::
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom.Custom",
- .tp_doc = "Custom objects",
+ .tp_doc = PyDoc_STR("Custom objects"),
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
@@ -161,7 +161,7 @@ you will need to OR the corresponding flags.
We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::
- .tp_doc = "Custom objects",
+ .tp_doc = PyDoc_STR("Custom objects"),
To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new`
handler. This is the equivalent of the Python method :meth:`__new__`, but
diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst
index c7b92c6ea24ca8..28d0350f6f114d 100644
--- a/Doc/extending/windows.rst
+++ b/Doc/extending/windows.rst
@@ -106,8 +106,7 @@ Using DLLs in Practice
Windows Python is built in Microsoft Visual C++; using other compilers may or
-may not work (though Borland seems to). The rest of this section is MSVC++
-specific.
+may not work. The rest of this section is MSVC++ specific.
When creating DLLs in Windows, you must pass :file:`pythonXY.lib` to the linker.
To build two DLLs, spam and ni (which uses C functions found in spam), you could
@@ -134,4 +133,3 @@ Developer Studio will throw in a lot of import libraries that you do not really
need, adding about 100K to your executable. To get rid of them, use the Project
Settings dialog, Link tab, to specify *ignore default libraries*. Add the
correct :file:`msvcrtxx.lib` to the list of libraries.
-
diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst
index 68570b33e2f626..a624fdb07a17df 100644
--- a/Doc/faq/design.rst
+++ b/Doc/faq/design.rst
@@ -266,12 +266,9 @@ For cases where you need to choose from a very large number of possibilities,
you can create a dictionary mapping case values to functions to call. For
example::
- def function_1(...):
- ...
-
functions = {'a': function_1,
'b': function_2,
- 'c': self.method_1, ...}
+ 'c': self.method_1}
func = functions[value]
func()
@@ -279,14 +276,14 @@ example::
For calling methods on objects, you can simplify yet further by using the
:func:`getattr` built-in to retrieve methods with a particular name::
- def visit_a(self, ...):
- ...
- ...
+ class MyVisitor:
+ def visit_a(self):
+ ...
- def dispatch(self, value):
- method_name = 'visit_' + str(value)
- method = getattr(self, method_name)
- method()
+ def dispatch(self, value):
+ method_name = 'visit_' + str(value)
+ method = getattr(self, method_name)
+ method()
It's suggested that you use a prefix for the method names, such as ``visit_`` in
this example. Without such a prefix, if values are coming from an untrusted
@@ -327,8 +324,7 @@ Can Python be compiled to machine code, C or some other language?
`Cython `_ compiles a modified version of Python with
optional annotations into C extensions. `Nuitka `_ is
an up-and-coming compiler of Python into C++ code, aiming to support the full
-Python language. For compiling to Java you can consider
-`VOC `_.
+Python language.
How does Python manage memory?
@@ -708,6 +704,15 @@ bindings are resolved at run-time in Python, and the second version only needs
to perform the resolution once.
+Why don't generators support the with statement?
+------------------------------------------------
+
+For technical reasons, a generator used directly as a context manager
+would not work correctly. When, as is most common, a generator is used as
+an iterator run to completion, no closing is needed. When it is, wrap
+it as "contextlib.closing(generator)" in the 'with' statement.
+
+
Why are colons required for the if/while/def/class statements?
--------------------------------------------------------------
diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst
index aecb56eaa4fd2f..1d2aca6f4c8d97 100644
--- a/Doc/faq/extending.rst
+++ b/Doc/faq/extending.rst
@@ -254,7 +254,6 @@ For Red Hat, install the python-devel RPM to get the necessary files.
For Debian, run ``apt-get install python-dev``.
-
How do I tell "incomplete input" from "invalid input"?
------------------------------------------------------
@@ -273,161 +272,6 @@ you. You can also set the :c:func:`PyOS_ReadlineFunctionPointer` to point at you
custom input function. See ``Modules/readline.c`` and ``Parser/myreadline.c``
for more hints.
-However sometimes you have to run the embedded Python interpreter in the same
-thread as your rest application and you can't allow the
-:c:func:`PyRun_InteractiveLoop` to stop while waiting for user input. The one
-solution then is to call :c:func:`PyParser_ParseString` and test for ``e.error``
-equal to ``E_EOF``, which means the input is incomplete. Here's a sample code
-fragment, untested, inspired by code from Alex Farber::
-
- #define PY_SSIZE_T_CLEAN
- #include
- #include
- #include
- #include
- #include
- #include
-
- int testcomplete(char *code)
- /* code should end in \n */
- /* return -1 for error, 0 for incomplete, 1 for complete */
- {
- node *n;
- perrdetail e;
-
- n = PyParser_ParseString(code, &_PyParser_Grammar,
- Py_file_input, &e);
- if (n == NULL) {
- if (e.error == E_EOF)
- return 0;
- return -1;
- }
-
- PyNode_Free(n);
- return 1;
- }
-
-Another solution is trying to compile the received string with
-:c:func:`Py_CompileString`. If it compiles without errors, try to execute the
-returned code object by calling :c:func:`PyEval_EvalCode`. Otherwise save the
-input for later. If the compilation fails, find out if it's an error or just
-more input is required - by extracting the message string from the exception
-tuple and comparing it to the string "unexpected EOF while parsing". Here is a
-complete example using the GNU readline library (you may want to ignore
-**SIGINT** while calling readline())::
-
- #include
- #include
-
- #define PY_SSIZE_T_CLEAN
- #include
- #include
- #include
- #include
-
- int main (int argc, char* argv[])
- {
- int i, j, done = 0; /* lengths of line, code */
- char ps1[] = ">>> ";
- char ps2[] = "... ";
- char *prompt = ps1;
- char *msg, *line, *code = NULL;
- PyObject *src, *glb, *loc;
- PyObject *exc, *val, *trb, *obj, *dum;
-
- Py_Initialize ();
- loc = PyDict_New ();
- glb = PyDict_New ();
- PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());
-
- while (!done)
- {
- line = readline (prompt);
-
- if (NULL == line) /* Ctrl-D pressed */
- {
- done = 1;
- }
- else
- {
- i = strlen (line);
-
- if (i > 0)
- add_history (line); /* save non-empty lines */
-
- if (NULL == code) /* nothing in code yet */
- j = 0;
- else
- j = strlen (code);
-
- code = realloc (code, i + j + 2);
- if (NULL == code) /* out of memory */
- exit (1);
-
- if (0 == j) /* code was empty, so */
- code[0] = '\0'; /* keep strncat happy */
-
- strncat (code, line, i); /* append line to code */
- code[i + j] = '\n'; /* append '\n' to code */
- code[i + j + 1] = '\0';
-
- src = Py_CompileString (code, "", Py_single_input);
-
- if (NULL != src) /* compiled just fine - */
- {
- if (ps1 == prompt || /* ">>> " or */
- '\n' == code[i + j - 1]) /* "... " and double '\n' */
- { /* so execute it */
- dum = PyEval_EvalCode (src, glb, loc);
- Py_XDECREF (dum);
- Py_XDECREF (src);
- free (code);
- code = NULL;
- if (PyErr_Occurred ())
- PyErr_Print ();
- prompt = ps1;
- }
- } /* syntax error or E_EOF? */
- else if (PyErr_ExceptionMatches (PyExc_SyntaxError))
- {
- PyErr_Fetch (&exc, &val, &trb); /* clears exception! */
-
- if (PyArg_ParseTuple (val, "sO", &msg, &obj) &&
- !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */
- {
- Py_XDECREF (exc);
- Py_XDECREF (val);
- Py_XDECREF (trb);
- prompt = ps2;
- }
- else /* some other syntax error */
- {
- PyErr_Restore (exc, val, trb);
- PyErr_Print ();
- free (code);
- code = NULL;
- prompt = ps1;
- }
- }
- else /* some non-syntax error */
- {
- PyErr_Print ();
- free (code);
- code = NULL;
- prompt = ps1;
- }
-
- free (line);
- }
- }
-
- Py_XDECREF(glb);
- Py_XDECREF(loc);
- Py_Finalize();
- exit(0);
- }
-
-
How do I find undefined g++ symbols __builtin_new or __pure_virtual?
--------------------------------------------------------------------
diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst
index cf70f16c6fe328..7723114bcc18d3 100644
--- a/Doc/faq/general.rst
+++ b/Doc/faq/general.rst
@@ -113,7 +113,7 @@ to many different classes of problems.
The language comes with a large standard library that covers areas such as
string processing (regular expressions, Unicode, calculating differences between
-files), Internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP, CGI
+files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP, CGI
programming), software engineering (unit testing, logging, profiling, parsing
Python code), and operating system interfaces (system calls, filesystems, TCP/IP
sockets). Look at the table of contents for :ref:`library-index` to get an idea
diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst
index 781da467d18013..86c56d957cdfec 100644
--- a/Doc/faq/gui.rst
+++ b/Doc/faq/gui.rst
@@ -14,17 +14,8 @@ Graphic User Interface FAQ
General GUI Questions
=====================
-What platform-independent GUI toolkits exist for Python?
-========================================================
-
-Depending on what platform(s) you are aiming at, there are several. Some
-of them haven't been ported to Python 3 yet. At least `Tkinter`_ and `Qt`_
-are known to be Python 3-compatible.
-
-.. XXX check links
-
-Tkinter
--------
+What GUI toolkits exist for Python?
+===================================
Standard builds of Python include an object-oriented interface to the Tcl/Tk
widget set, called :ref:`tkinter `. This is probably the easiest to
@@ -32,85 +23,14 @@ install (since it comes included with most
`binary distributions `_ of Python) and use.
For more info about Tk, including pointers to the source, see the
`Tcl/Tk home page `_. Tcl/Tk is fully portable to the
-Mac OS X, Windows, and Unix platforms.
-
-wxWidgets
----------
-
-wxWidgets (https://www.wxwidgets.org) is a free, portable GUI class
-library written in C++ that provides a native look and feel on a
-number of platforms, with Windows, Mac OS X, GTK, X11, all listed as
-current stable targets. Language bindings are available for a number
-of languages including Python, Perl, Ruby, etc.
-
-`wxPython `_ is the Python binding for
-wxwidgets. While it often lags slightly behind the official wxWidgets
-releases, it also offers a number of features via pure Python
-extensions that are not available in other language bindings. There
-is an active wxPython user and developer community.
-
-Both wxWidgets and wxPython are free, open source, software with
-permissive licences that allow their use in commercial products as
-well as in freeware or shareware.
-
-
-Qt
----
-
-There are bindings available for the Qt toolkit (using either `PyQt
-`_ or `PySide
-`_) and for KDE (`PyKDE4 `__).
-PyQt is currently more mature than PySide, but you must buy a PyQt license from
-`Riverbank Computing `_
-if you want to write proprietary applications. PySide is free for all applications.
-
-Qt 4.5 upwards is licensed under the LGPL license; also, commercial licenses
-are available from `The Qt Company `_.
-
-Gtk+
-----
-
-The `GObject introspection bindings `_
-for Python allow you to write GTK+ 3 applications. There is also a
-`Python GTK+ 3 Tutorial `_.
-
-The older PyGtk bindings for the `Gtk+ 2 toolkit `_ have
-been implemented by James Henstridge; see .
-
-Kivy
-----
-
-`Kivy `_ is a cross-platform GUI library supporting both
-desktop operating systems (Windows, macOS, Linux) and mobile devices (Android,
-iOS). It is written in Python and Cython, and can use a range of windowing
-backends.
-
-Kivy is free and open source software distributed under the MIT license.
-
-FLTK
-----
-
-Python bindings for `the FLTK toolkit `_, a simple yet
-powerful and mature cross-platform windowing system, are available from `the
-PyFLTK project `_.
-
-OpenGL
-------
-
-For OpenGL bindings, see `PyOpenGL `_.
-
-
-What platform-specific GUI toolkits exist for Python?
-========================================================
-
-By installing the `PyObjc Objective-C bridge
-`_, Python programs can use Mac OS X's
-Cocoa libraries.
-
-:ref:`Pythonwin ` by Mark Hammond includes an interface to the
-Microsoft Foundation Classes and a Python programming environment
-that's written mostly in Python using the MFC classes.
-
+macOS, Windows, and Unix platforms.
+
+Depending on what platform(s) you are aiming at, there are also several
+alternatives. A `list of cross-platform
+`_ and
+`platform-specific
+`_ GUI
+frameworks can be found on the python wiki.
Tkinter questions
=================
diff --git a/Doc/faq/installed.rst b/Doc/faq/installed.rst
index 42296533e26f32..16c9a74daffb1d 100644
--- a/Doc/faq/installed.rst
+++ b/Doc/faq/installed.rst
@@ -29,7 +29,7 @@ there are several possible ways it could have gotten there.
* Some Windows machines also have Python installed. At this writing we're aware
of computers from Hewlett-Packard and Compaq that include Python. Apparently
some of HP/Compaq's administrative tools are written in Python.
-* Many Unix-compatible operating systems, such as Mac OS X and some Linux
+* Many Unix-compatible operating systems, such as macOS and some Linux
distributions, have Python installed by default; it's included in the base
installation.
diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst
index 4d27abd4351ec0..8167bf22f0b1ad 100644
--- a/Doc/faq/library.rst
+++ b/Doc/faq/library.rst
@@ -20,7 +20,7 @@ library and will be able to skip this step.)
For third-party packages, search the `Python Package Index
`_ or try `Google `_ or
-another Web search engine. Searching for "Python" plus a keyword or two for
+another web search engine. Searching for "Python" plus a keyword or two for
your topic of interest will usually find something helpful.
@@ -106,9 +106,6 @@ support, pads, and mouse support. This means the module isn't compatible with
operating systems that only have BSD curses, but there don't seem to be any
currently maintained OSes that fall into this category.
-For Windows: use `the consolelib module
-`_.
-
Is there an equivalent to C's onexit() in Python?
-------------------------------------------------
@@ -243,9 +240,6 @@ Be sure to use the :mod:`threading` module and not the :mod:`_thread` module.
The :mod:`threading` module builds convenient abstractions on top of the
low-level primitives provided by the :mod:`_thread` module.
-Aahz has a set of slides from his threading tutorial that are helpful; see
-http://www.pythoncraft.com/OSCON2001/.
-
None of my threads seem to run: why?
------------------------------------
@@ -489,8 +483,14 @@ including :func:`~shutil.copyfile`, :func:`~shutil.copytree`, and
How do I copy a file?
---------------------
-The :mod:`shutil` module contains a :func:`~shutil.copyfile` function. Note
-that on MacOS 9 it doesn't copy the resource fork and Finder info.
+The :mod:`shutil` module contains a :func:`~shutil.copyfile` function.
+Note that on Windows NTFS volumes, it does not copy
+`alternate data streams
+`_
+nor `resource forks `__
+on macOS HFS+ volumes, though both are now rarely used.
+It also doesn't copy file permissions and metadata, though using
+:func:`shutil.copy2` instead will preserve most (though not all) of it.
How do I read (or write) binary data?
@@ -617,9 +617,9 @@ use ``p.read(n)``.
How do I access the serial (RS232) port?
----------------------------------------
-For Win32, POSIX (Linux, BSD, etc.), Jython:
+For Win32, OSX, Linux, BSD, Jython, IronPython:
- http://pyserial.sourceforge.net
+ https://pypi.org/project/pyserial/
For Unix, see a Usenet post by Mitch Chapman:
@@ -670,7 +670,7 @@ A summary of available frameworks is maintained by Paul Boddie at
https://wiki.python.org/moin/WebProgramming\ .
Cameron Laird maintains a useful set of pages about Python web technologies at
-http://phaseit.net/claird/comp.lang.python/web_python.
+https://web.archive.org/web/20210224183619/http://phaseit.net/claird/comp.lang.python/web_python.
How can I mimic CGI form submission (METHOD=POST)?
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index ed03c494388805..efd7a5ae00269c 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -56,7 +56,7 @@ Are there tools to help find bugs or perform static analysis?
Yes.
-`Pylint `_ and
+`Pylint `_ and
`Pyflakes `_ do basic checking that will
help you catch bugs sooner.
@@ -66,6 +66,8 @@ Static type checkers such as `Mypy `_,
source code.
+.. _faq-create-standalone-binary:
+
How can I create a stand-alone binary from a Python script?
-----------------------------------------------------------
@@ -76,7 +78,7 @@ set of modules required by a program and bind these modules together with a
Python binary to produce a single executable.
One is to use the freeze tool, which is included in the Python source tree as
-``Tools/freeze``. It converts Python byte code to C arrays; a C compiler you can
+``Tools/freeze``. It converts Python byte code to C arrays; with a C compiler you can
embed all your modules into a new program, which is then linked with the
standard Python modules.
@@ -89,14 +91,15 @@ only contains those built-in modules which are actually used in the program. It
then compiles the generated C code and links it with the rest of the Python
interpreter to form a self-contained binary which acts exactly like your script.
-Obviously, freeze requires a C compiler. There are several other utilities
-which don't:
-
-* `py2exe `_ for Windows binaries
-* `py2app `_ for Mac OS X binaries
-* `cx_Freeze `_ for cross-platform
- binaries
+The following packages can help with the creation of console and GUI
+executables:
+* `Nuitka `_ (Cross-platform)
+* `PyInstaller `_ (Cross-platform)
+* `PyOxidizer `_ (Cross-platform)
+* `cx_Freeze `_ (Cross-platform)
+* `py2app `_ (macOS only)
+* `py2exe `_ (Windows only)
Are there coding standards or a style guide for Python programs?
----------------------------------------------------------------
@@ -406,8 +409,9 @@ What is the difference between arguments and parameters?
:term:`Parameters ` are defined by the names that appear in a
function definition, whereas :term:`arguments ` are the values
-actually passed to a function when calling it. Parameters define what types of
-arguments a function can accept. For example, given the function definition::
+actually passed to a function when calling it. Parameters define what
+:term:`kind of arguments ` a function can accept. For
+example, given the function definition::
def func(foo, bar=None, **kwargs):
pass
@@ -833,6 +837,27 @@ ago? ``-190 % 12 == 2`` is useful; ``-190 % 12 == -10`` is a bug waiting to
bite.
+How do I get int literal attribute instead of SyntaxError?
+----------------------------------------------------------
+
+Trying to lookup an ``int`` literal attribute in the normal manner gives
+a syntax error because the period is seen as a decimal point::
+
+ >>> 1.__class__
+ File "", line 1
+ 1.__class__
+ ^
+ SyntaxError: invalid decimal literal
+
+The solution is to separate the literal from the period
+with either a space or parentheses.
+
+ >>> 1 .__class__
+
+ >>> (1).__class__
+
+
+
How do I convert a string to a number?
--------------------------------------
@@ -1795,7 +1820,7 @@ for ``None``. This reads like plain English in code and avoids confusion with
other objects that may have boolean values that evaluate to false.
2) Detecting optional arguments can be tricky when ``None`` is a valid input
-value. In those situations, you can create an singleton sentinel object
+value. In those situations, you can create a singleton sentinel object
guaranteed to be distinct from other objects. For example, here is how
to implement a method that behaves like :meth:`dict.pop`::
@@ -1824,6 +1849,134 @@ For example, here is the implementation of
return False
+How can a subclass control what data is stored in an immutable instance?
+------------------------------------------------------------------------
+
+When subclassing an immutable type, override the :meth:`__new__` method
+instead of the :meth:`__init__` method. The latter only runs *after* an
+instance is created, which is too late to alter data in an immutable
+instance.
+
+All of these immutable classes have a different signature than their
+parent class:
+
+.. testcode::
+
+ from datetime import date
+
+ class FirstOfMonthDate(date):
+ "Always choose the first day of the month"
+ def __new__(cls, year, month, day):
+ return super().__new__(cls, year, month, 1)
+
+ class NamedInt(int):
+ "Allow text names for some numbers"
+ xlat = {'zero': 0, 'one': 1, 'ten': 10}
+ def __new__(cls, value):
+ value = cls.xlat.get(value, value)
+ return super().__new__(cls, value)
+
+ class TitleStr(str):
+ "Convert str to name suitable for a URL path"
+ def __new__(cls, s):
+ s = s.lower().replace(' ', '-')
+ s = ''.join([c for c in s if c.isalnum() or c == '-'])
+ return super().__new__(cls, s)
+
+The classes can be used like this:
+
+.. doctest::
+
+ >>> FirstOfMonthDate(2012, 2, 14)
+ FirstOfMonthDate(2012, 2, 1)
+ >>> NamedInt('ten')
+ 10
+ >>> NamedInt(20)
+ 20
+ >>> TitleStr('Blog: Why Python Rocks')
+ 'blog-why-python-rocks'
+
+
+How do I cache method calls?
+----------------------------
+
+The two principal tools for caching methods are
+:func:`functools.cached_property` and :func:`functools.lru_cache`. The
+former stores results at the instance level and the latter at the class
+level.
+
+The *cached_property* approach only works with methods that do not take
+any arguments. It does not create a reference to the instance. The
+cached method result will be kept only as long as the instance is alive.
+
+The advantage is that when an instance is no longer used, the cached
+method result will be released right away. The disadvantage is that if
+instances accumulate, so too will the accumulated method results. They
+can grow without bound.
+
+The *lru_cache* approach works with methods that have hashable
+arguments. It creates a reference to the instance unless special
+efforts are made to pass in weak references.
+
+The advantage of the least recently used algorithm is that the cache is
+bounded by the specified *maxsize*. The disadvantage is that instances
+are kept alive until they age out of the cache or until the cache is
+cleared.
+
+This example shows the various techniques::
+
+ class Weather:
+ "Lookup weather information on a government website"
+
+ def __init__(self, station_id):
+ self._station_id = station_id
+ # The _station_id is private and immutable
+
+ def current_temperature(self):
+ "Latest hourly observation"
+ # Do not cache this because old results
+ # can be out of date.
+
+ @cached_property
+ def location(self):
+ "Return the longitude/latitude coordinates of the station"
+ # Result only depends on the station_id
+
+ @lru_cache(maxsize=20)
+ def historic_rainfall(self, date, units='mm'):
+ "Rainfall on a given date"
+ # Depends on the station_id, date, and units.
+
+The above example assumes that the *station_id* never changes. If the
+relevant instance attributes are mutable, the *cached_property* approach
+can't be made to work because it cannot detect changes to the
+attributes.
+
+The *lru_cache* approach can be made to work, but the class needs to define the
+*__eq__* and *__hash__* methods so the cache can detect relevant attribute
+updates::
+
+ class Weather:
+ "Example with a mutable station identifier"
+
+ def __init__(self, station_id):
+ self.station_id = station_id
+
+ def change_station(self, station_id):
+ self.station_id = station_id
+
+ def __eq__(self, other):
+ return self.station_id == other.station_id
+
+ def __hash__(self):
+ return hash(self.station_id)
+
+ @lru_cache(maxsize=20)
+ def historic_rainfall(self, date, units='cm'):
+ 'Rainfall on a given date'
+ # Depends on the station_id, date, and units.
+
+
Modules
=======
@@ -1940,7 +2093,7 @@ Jim Roskind suggests performing steps in the following order in each module:
* ``import`` statements
* active code (including globals that are initialized from imported values).
-van Rossum doesn't like this approach much because the imports appear in a
+Van Rossum doesn't like this approach much because the imports appear in a
strange place, but it does work.
Matthias Urlichs recommends restructuring your code so that the recursive import
diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst
index 186dac2e255b37..4f50b3f1b93f1a 100644
--- a/Doc/faq/windows.rst
+++ b/Doc/faq/windows.rst
@@ -26,8 +26,8 @@ with running programs from the Windows command line then everything will seem
obvious; otherwise, you might need a little more guidance.
Unless you use some sort of integrated development environment, you will end up
-*typing* Windows commands into what is variously referred to as a "DOS window"
-or "Command prompt window". Usually you can create such a window from your
+*typing* Windows commands into what is referred to as a
+"Command prompt window". Usually you can create such a window from your
search bar by searching for ``cmd``. You should be able to recognize
when you have started such a window because you will see a Windows "command
prompt", which usually looks like this:
@@ -140,9 +140,8 @@ offender.
How do I make an executable from a Python script?
-------------------------------------------------
-See `cx_Freeze `_ and
-`py2exe `_, both are distutils extensions
-that allow you to create console and GUI executables from Python code.
+See :ref:`faq-create-standalone-binary` for a list of tools that can be used to
+make executables.
Is a ``*.pyd`` file the same as a DLL?
@@ -187,9 +186,6 @@ Embedding the Python interpreter in a Windows app can be summarized as follows:
by the Windows ``GetProcAddress()`` routine. Macros can make using these
pointers transparent to any C code that calls routines in Python's C API.
- Borland note: convert :file:`python{NN}.lib` to OMF format using Coff2Omf.exe
- first.
-
.. XXX what about static linking?
2. If you use SWIG, it is easy to create a Python "extension module" that will
@@ -280,4 +276,3 @@ How do I check for a keypress without blocking?
Use the :mod:`msvcrt` module. This is a standard Windows-specific extension module.
It defines a function ``kbhit()`` which checks whether a keyboard hit is
present, and ``getch()`` which gets one character without echoing it.
-
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 29c68ed72c6d70..62c9b867ca12e3 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -292,12 +292,12 @@ Glossary
The decorator syntax is merely syntactic sugar, the following two
function definitions are semantically equivalent::
- def f(...):
+ def f(arg):
...
f = staticmethod(f)
@staticmethod
- def f(...):
+ def f(arg):
...
The same concept exists for classes, but is less commonly used there. See
@@ -461,12 +461,13 @@ Glossary
for best practices on working with annotations.
__future__
- A pseudo-module which programmers can use to enable new language features
- which are not compatible with the current interpreter.
-
- By importing the :mod:`__future__` module and evaluating its variables,
- you can see when a new feature was first added to the language and when it
- becomes the default::
+ A :ref:`future statement `, ``from __future__ import ``,
+ directs the compiler to compile the current module using syntax or
+ semantics that will become standard in a future release of Python.
+ The :mod:`__future__` module documents the possible values of
+ *feature*. By importing this module and evaluating its variables,
+ you can see when a new feature was first added to the language and
+ when it will (or did) become the default::
>>> import __future__
>>> __future__.division
@@ -519,12 +520,13 @@ Glossary
:func:`functools.singledispatch` decorator, and :pep:`443`.
generic type
- A :term:`type` that can be parameterized; typically a container like
- :class:`list`. Used for :term:`type hints ` and
+ A :term:`type` that can be parameterized; typically a
+ :ref:`container class` such as :class:`list` or
+ :class:`dict`. Used for :term:`type hints ` and
:term:`annotations `.
- See :pep:`483` for more details, and :mod:`typing` or
- :ref:`generic alias type ` for its uses.
+ For more details, see :ref:`generic alias types`,
+ :pep:`483`, :pep:`484`, :pep:`585`, and the :mod:`typing` module.
GIL
See :term:`global interpreter lock`.
@@ -667,6 +669,11 @@ Glossary
More information can be found in :ref:`typeiter`.
+ .. impl-detail::
+
+ CPython does not consistently apply the requirement that an iterator
+ define :meth:`__iter__`.
+
key function
A key function or collation function is a callable that returns a value
used for sorting or ordering. For example, :func:`locale.strxfrm` is
@@ -712,7 +719,7 @@ Glossary
On Unix, it is the encoding of the LC_CTYPE locale. It can be set with
``locale.setlocale(locale.LC_CTYPE, new_locale)``.
- On Windows, it is is the ANSI code page (ex: ``cp1252``).
+ On Windows, it is the ANSI code page (ex: ``cp1252``).
``locale.getpreferredencoding(False)`` can be used to get the locale
encoding.
@@ -1129,7 +1136,16 @@ Glossary
See also :term:`borrowed reference`.
text encoding
- A codec which encodes Unicode strings to bytes.
+ A string in Python is a sequence of Unicode code points (in range
+ ``U+0000``--``U+10FFFF``). To store or transfer a string, it needs to be
+ serialized as a sequence of bytes.
+
+ Serializing a string into a sequence of bytes is known as "encoding", and
+ recreating the string from the sequence of bytes is known as "decoding".
+
+ There are a variety of different text serialization
+ :ref:`codecs `, which are collectively referred to as
+ "text encodings".
text file
A :term:`file object` able to read and write :class:`str` objects.
diff --git a/Doc/howto/annotations.rst b/Doc/howto/annotations.rst
index 3e61103e99c9a6..2bc2f2d4c839e2 100644
--- a/Doc/howto/annotations.rst
+++ b/Doc/howto/annotations.rst
@@ -156,7 +156,7 @@ Manually Un-Stringizing Stringized Annotations
require annotating with string values that specifically
*can't* be evaluated. For example:
- * :pep:`604` union types using `|`, before support for this
+ * :pep:`604` union types using ``|``, before support for this
was added to Python 3.10.
* Definitions that aren't needed at runtime, only imported
when :const:`typing.TYPE_CHECKING` is true.
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 3a3653a5ee3a3e..f2195405fe96fe 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -1350,7 +1350,7 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``
/*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/
This block adds a converter to Argument Clinic named ``ssize_t``. Parameters
-declared as ``ssize_t`` will be declared as type ``Py_ssize_t``, and will
+declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will
be parsed by the ``'O&'`` format unit, which will call the
``ssize_t_converter`` converter function. ``ssize_t`` variables
automatically support default values.
diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst
index cc4b4785b12290..c0149ffff37716 100644
--- a/Doc/howto/curses.rst
+++ b/Doc/howto/curses.rst
@@ -55,11 +55,7 @@ everything, though.
The Windows version of Python doesn't include the :mod:`curses`
module. A ported version called `UniCurses
-`_ is available. You could
-also try `the Console module `_
-written by Fredrik Lundh, which doesn't
-use the same API as curses but provides cursor-addressable text output
-and full support for mouse and keyboard input.
+`_ is available.
The Python curses module
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index 575caeb720f3d0..f2e2f7ee68c2e2 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -696,10 +696,14 @@ a pure Python equivalent:
>>> b.g == b['g'] == ('getattr_hook', b, 'g')
True
+Note, there is no :meth:`__getattr__` hook in the :meth:`__getattribute__`
+code. That is why calling :meth:`__getattribute__` directly or with
+``super().__getattribute__`` will bypass :meth:`__getattr__` entirely.
-Interestingly, attribute lookup doesn't call :meth:`object.__getattribute__`
-directly. Instead, both the dot operator and the :func:`getattr` function
-perform attribute lookup by way of a helper function:
+Instead, it is the dot operator and the :func:`getattr` function that are
+responsible for invoking :meth:`__getattr__` whenever :meth:`__getattribute__`
+raises an :exc:`AttributeError`. Their logic is encapsulated in a helper
+function:
.. testcode::
@@ -744,12 +748,6 @@ perform attribute lookup by way of a helper function:
...
AttributeError: 'ClassWithoutGetAttr' object has no attribute 'z'
-So if :meth:`__getattr__` exists, it is called whenever :meth:`__getattribute__`
-raises :exc:`AttributeError` (either directly or in one of the descriptor calls).
-
-Also, if a user calls :meth:`object.__getattribute__` directly, the
-:meth:`__getattr__` hook is bypassed entirely.
-
Invocation from a class
-----------------------
@@ -1264,6 +1262,9 @@ Using the non-data descriptor protocol, a pure Python version of
def __get__(self, obj, objtype=None):
return self.f
+ def __call__(self, *args, **kwds):
+ return self.f(*args, **kwds)
+
.. testcode::
:hide:
@@ -1272,6 +1273,8 @@ Using the non-data descriptor protocol, a pure Python version of
def f(x):
return x * 10
+ wrapped_ord = StaticMethod(ord)
+
.. doctest::
:hide:
@@ -1279,6 +1282,8 @@ Using the non-data descriptor protocol, a pure Python version of
30
>>> E_sim().f(3)
30
+ >>> wrapped_ord('A')
+ 65
Class methods
@@ -1344,7 +1349,7 @@ Using the non-data descriptor protocol, a pure Python version of
if cls is None:
cls = type(obj)
if hasattr(type(self.f), '__get__'):
- return self.f.__get__(cls)
+ return self.f.__get__(cls, cls)
return MethodType(self.f, cls)
.. testcode::
@@ -1537,7 +1542,7 @@ variables:
'Simulate how the type metaclass adds member objects for slots'
def __new__(mcls, clsname, bases, mapping):
- 'Emuluate type_new() in Objects/typeobject.c'
+ 'Emulate type_new() in Objects/typeobject.c'
# type_new() calls PyTypeReady() which calls add_methods()
slot_names = mapping.get('slot_names', [])
for offset, name in enumerate(slot_names):
diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst
deleted file mode 100644
index 9ece93e660504f..00000000000000
--- a/Doc/howto/enum.rst
+++ /dev/null
@@ -1,1416 +0,0 @@
-==========
-Enum HOWTO
-==========
-
-:Author: Ethan Furman
-
-.. _enum-basic-tutorial:
-
-.. currentmodule:: enum
-
-Basic Enum Tutorial
--------------------
-
-An :class:`Enum` is a set of symbolic names bound to unique values. They are
-similar to global variables, but they offer a more useful :func:`repr()`,
-grouping, type-safety, and a few other features.
-
-They are most useful when you have a variable that can take one of a limited
-selection of values. For example, the days of the week::
-
- >>> from enum import Enum
- >>> class Weekday(Enum):
- ... MONDAY = 1
- ... TUESDAY = 2
- ... WEDNESDAY = 3
- ... THURSDAY = 4
- ... FRIDAY = 5
- ... SATURDAY = 6
- ... SUNDAY = 7
-
-As you can see, creating an :class:`Enum` is as simple as writing a class that
-inherits from :class:`Enum` itself.
-
-.. note:: Case of Enum Members
-
- Because Enums are used to represent constants we recommend using
- UPPER_CASE names for members, and will be using that style in our examples.
-
-Depending on the nature of the enum a member's value may or may not be
-important, but either way that value can be used to get the corresponding
-member::
-
- >>> Weekday(3)
- Weekday.WEDNESDAY
-
-As you can see, the ``repr()`` of a member shows the enum name and the
-member name. The ``str()`` on a member shows only its name::
-
- >>> print(Weekday.THURSDAY)
- THURSDAY
-
-The *type* of an enumeration member is the enum it belongs to::
-
- >>> type(Weekday.MONDAY)
-
- >>> isinstance(Weekday.FRIDAY, Weekday)
- True
-
-Enum members have an attribute that contains just their :attr:`name`::
-
- >>> print(Weekday.TUESDAY.name)
- TUESDAY
-
-Likewise, they have an attribute for their :attr:`value`::
-
-
- >>> Weekday.WEDNESDAY.value
- 3
-
-Unlike many languages that treat enumerations solely as name/value pairs,
-Python Enums can have behavior added. For example, :class:`datetime.date`
-has two methods for returning the weekday: :meth:`weekday` and :meth:`isoweekday`.
-The difference is that one of them counts from 0-6 and the other from 1-7.
-Rather than keep track of that ourselves we can add a method to the :class:`Weekday`
-enum to extract the day from the :class:`date` instance and return the matching
-enum member::
-
- @classmethod
- def from_date(cls, date):
- return cls(date.isoweekday())
-
-The complete :class:`Weekday` enum now looks like this::
-
- >>> class Weekday(Enum):
- ... MONDAY = 1
- ... TUESDAY = 2
- ... WEDNESDAY = 3
- ... THURSDAY = 4
- ... FRIDAY = 5
- ... SATURDAY = 6
- ... SUNDAY = 7
- ... #
- ... @classmethod
- ... def from_date(cls, date):
- ... return cls(date.isoweekday())
-
-Now we can find out what today is! Observe::
-
- >>> from datetime import date
- >>> Weekday.from_date(date.today())
- Weekday.TUESDAY
-
-Of course, if you're reading this on some other day, you'll see that day instead.
-
-This :class:`Weekday` enum is great if our variable only needs one day, but
-what if we need several? Maybe we're writing a function to plot chores during
-a week, and don't want to use a :class:`list` -- we could use a different type
-of :class:`Enum`::
-
- >>> from enum import Flag
- >>> class Weekday(Flag):
- ... MONDAY = 1
- ... TUESDAY = 2
- ... WEDNESDAY = 4
- ... THURSDAY = 8
- ... FRIDAY = 16
- ... SATURDAY = 32
- ... SUNDAY = 64
-
-We've changed two things: we're inherited from :class:`Flag`, and the values are
-all powers of 2.
-
-Just like the original :class:`Weekday` enum above, we can have a single selection::
-
- >>> first_week_day = Weekday.MONDAY
- >>> first_week_day
- Weekday.MONDAY
-
-But :class:`Flag` also allows us to combine several members into a single
-variable::
-
- >>> weekend = Weekday.SATURDAY | Weekday.SUNDAY
- >>> weekend
- Weekday.SATURDAY|Weekday.SUNDAY
-
-You can even iterate over a :class:`Flag` variable::
-
- >>> for day in weekend:
- ... print(day)
- SATURDAY
- SUNDAY
-
-Okay, let's get some chores set up::
-
- >>> chores_for_ethan = {
- ... 'feed the cat': Weekday.MONDAY | Weekday.WEDNESDAY | Weekday.FRIDAY,
- ... 'do the dishes': Weekday.TUESDAY | Weekday.THURSDAY,
- ... 'answer SO questions': Weekday.SATURDAY,
- ... }
-
-And a function to display the chores for a given day::
-
- >>> def show_chores(chores, day):
- ... for chore, days in chores.items():
- ... if day in days:
- ... print(chore)
- >>> show_chores(chores_for_ethan, Weekday.SATURDAY)
- answer SO questions
-
-In cases where the actual values of the members do not matter, you can save
-yourself some work and use :func:`auto()` for the values::
-
- >>> from enum import auto
- >>> class Weekday(Flag):
- ... MONDAY = auto()
- ... TUESDAY = auto()
- ... WEDNESDAY = auto()
- ... THURSDAY = auto()
- ... FRIDAY = auto()
- ... SATURDAY = auto()
- ... SUNDAY = auto()
-
-
-.. _enum-advanced-tutorial:
-
-Programmatic access to enumeration members and their attributes
----------------------------------------------------------------
-
-Sometimes it's useful to access members in enumerations programmatically (i.e.
-situations where ``Color.RED`` won't do because the exact color is not known
-at program-writing time). ``Enum`` allows such access::
-
- >>> Color(1)
- Color.RED
- >>> Color(3)
- Color.BLUE
-
-If you want to access enum members by *name*, use item access::
-
- >>> Color['RED']
- Color.RED
- >>> Color['GREEN']
- Color.GREEN
-
-If you have an enum member and need its :attr:`name` or :attr:`value`::
-
- >>> member = Color.RED
- >>> member.name
- 'RED'
- >>> member.value
- 1
-
-
-Duplicating enum members and values
------------------------------------
-
-Having two enum members with the same name is invalid::
-
- >>> class Shape(Enum):
- ... SQUARE = 2
- ... SQUARE = 3
- ...
- Traceback (most recent call last):
- ...
- TypeError: 'SQUARE' already defined as: 2
-
-However, an enum member can have other names associated with it. Given two
-entries ``A`` and ``B`` with the same value (and ``A`` defined first), ``B``
-is an alias for the member ``A``. By-value lookup of the value of ``A`` will
-return the member ``A``. By-name lookup of ``A`` will return the member ``A``.
-By-name lookup of ``B`` will also return the member ``A``::
-
- >>> class Shape(Enum):
- ... SQUARE = 2
- ... DIAMOND = 1
- ... CIRCLE = 3
- ... ALIAS_FOR_SQUARE = 2
- ...
- >>> Shape.SQUARE
- Shape.SQUARE
- >>> Shape.ALIAS_FOR_SQUARE
- Shape.SQUARE
- >>> Shape(2)
- Shape.SQUARE
-
-.. note::
-
- Attempting to create a member with the same name as an already
- defined attribute (another member, a method, etc.) or attempting to create
- an attribute with the same name as a member is not allowed.
-
-
-Ensuring unique enumeration values
-----------------------------------
-
-By default, enumerations allow multiple names as aliases for the same value.
-When this behavior isn't desired, you can use the :func:`unique` decorator::
-
- >>> from enum import Enum, unique
- >>> @unique
- ... class Mistake(Enum):
- ... ONE = 1
- ... TWO = 2
- ... THREE = 3
- ... FOUR = 3
- ...
- Traceback (most recent call last):
- ...
- ValueError: duplicate values found in : FOUR -> THREE
-
-
-Using automatic values
-----------------------
-
-If the exact value is unimportant you can use :class:`auto`::
-
- >>> from enum import Enum, auto
- >>> class Color(Enum):
- ... RED = auto()
- ... BLUE = auto()
- ... GREEN = auto()
- ...
- >>> [member.value for member in Color]
- [1, 2, 3]
-
-The values are chosen by :func:`_generate_next_value_`, which can be
-overridden::
-
- >>> class AutoName(Enum):
- ... def _generate_next_value_(name, start, count, last_values):
- ... return name
- ...
- >>> class Ordinal(AutoName):
- ... NORTH = auto()
- ... SOUTH = auto()
- ... EAST = auto()
- ... WEST = auto()
- ...
- >>> [member.value for member in Color]
- ['NORTH', 'SOUTH', 'EAST', 'WEST']
-
-.. note::
-
- The :meth:`_generate_next_value_` method must be defined before any members.
-
-Iteration
----------
-
-Iterating over the members of an enum does not provide the aliases::
-
- >>> list(Shape)
- [Shape.SQUARE, Shape.DIAMOND, Shape.CIRCLE]
-
-The special attribute ``__members__`` is a read-only ordered mapping of names
-to members. It includes all names defined in the enumeration, including the
-aliases::
-
- >>> for name, member in Shape.__members__.items():
- ... name, member
- ...
- ('SQUARE', Shape.SQUARE)
- ('DIAMOND', Shape.DIAMOND)
- ('CIRCLE', Shape.CIRCLE)
- ('ALIAS_FOR_SQUARE', Shape.SQUARE)
-
-The ``__members__`` attribute can be used for detailed programmatic access to
-the enumeration members. For example, finding all the aliases::
-
- >>> [name for name, member in Shape.__members__.items() if member.name != name]
- ['ALIAS_FOR_SQUARE']
-
-
-Comparisons
------------
-
-Enumeration members are compared by identity::
-
- >>> Color.RED is Color.RED
- True
- >>> Color.RED is Color.BLUE
- False
- >>> Color.RED is not Color.BLUE
- True
-
-Ordered comparisons between enumeration values are *not* supported. Enum
-members are not integers (but see `IntEnum`_ below)::
-
- >>> Color.RED < Color.BLUE
- Traceback (most recent call last):
- File "", line 1, in
- TypeError: '<' not supported between instances of 'Color' and 'Color'
-
-Equality comparisons are defined though::
-
- >>> Color.BLUE == Color.RED
- False
- >>> Color.BLUE != Color.RED
- True
- >>> Color.BLUE == Color.BLUE
- True
-
-Comparisons against non-enumeration values will always compare not equal
-(again, :class:`IntEnum` was explicitly designed to behave differently, see
-below)::
-
- >>> Color.BLUE == 2
- False
-
-
-Allowed members and attributes of enumerations
-----------------------------------------------
-
-Most of the examples above use integers for enumeration values. Using integers is
-short and handy (and provided by default by the `Functional API`_), but not
-strictly enforced. In the vast majority of use-cases, one doesn't care what
-the actual value of an enumeration is. But if the value *is* important,
-enumerations can have arbitrary values.
-
-Enumerations are Python classes, and can have methods and special methods as
-usual. If we have this enumeration::
-
- >>> class Mood(Enum):
- ... FUNKY = 1
- ... HAPPY = 3
- ...
- ... def describe(self):
- ... # self is the member here
- ... return self.name, self.value
- ...
- ... def __str__(self):
- ... return 'my custom str! {0}'.format(self.value)
- ...
- ... @classmethod
- ... def favorite_mood(cls):
- ... # cls here is the enumeration
- ... return cls.HAPPY
- ...
-
-Then::
-
- >>> Mood.favorite_mood()
- Mood.HAPPY
- >>> Mood.HAPPY.describe()
- ('HAPPY', 3)
- >>> str(Mood.FUNKY)
- 'my custom str! 1'
-
-The rules for what is allowed are as follows: names that start and end with
-a single underscore are reserved by enum and cannot be used; all other
-attributes defined within an enumeration will become members of this
-enumeration, with the exception of special methods (:meth:`__str__`,
-:meth:`__add__`, etc.), descriptors (methods are also descriptors), and
-variable names listed in :attr:`_ignore_`.
-
-Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__` then
-any value(s) given to the enum member will be passed into those methods.
-See `Planet`_ for an example.
-
-
-Restricted Enum subclassing
----------------------------
-
-A new :class:`Enum` class must have one base enum class, up to one concrete
-data type, and as many :class:`object`-based mixin classes as needed. The
-order of these base classes is::
-
- class EnumName([mix-in, ...,] [data-type,] base-enum):
- pass
-
-Also, subclassing an enumeration is allowed only if the enumeration does not define
-any members. So this is forbidden::
-
- >>> class MoreColor(Color):
- ... PINK = 17
- ...
- Traceback (most recent call last):
- ...
- TypeError: MoreColor: cannot extend enumeration 'Color'
-
-But this is allowed::
-
- >>> class Foo(Enum):
- ... def some_behavior(self):
- ... pass
- ...
- >>> class Bar(Foo):
- ... HAPPY = 1
- ... SAD = 2
- ...
-
-Allowing subclassing of enums that define members would lead to a violation of
-some important invariants of types and instances. On the other hand, it makes
-sense to allow sharing some common behavior between a group of enumerations.
-(See `OrderedEnum`_ for an example.)
-
-
-Pickling
---------
-
-Enumerations can be pickled and unpickled::
-
- >>> from test.test_enum import Fruit
- >>> from pickle import dumps, loads
- >>> Fruit.TOMATO is loads(dumps(Fruit.TOMATO))
- True
-
-The usual restrictions for pickling apply: picklable enums must be defined in
-the top level of a module, since unpickling requires them to be importable
-from that module.
-
-.. note::
-
- With pickle protocol version 4 it is possible to easily pickle enums
- nested in other classes.
-
-It is possible to modify how enum members are pickled/unpickled by defining
-:meth:`__reduce_ex__` in the enumeration class.
-
-
-Functional API
---------------
-
-The :class:`Enum` class is callable, providing the following functional API::
-
- >>> Animal = Enum('Animal', 'ANT BEE CAT DOG')
- >>> Animal
-
- >>> Animal.ANT
- Animal.ANT
- >>> Animal.ANT.value
- 1
- >>> list(Animal)
- [Animal.ANT, Animal.BEE, Animal.CAT, Animal.DOG]
-
-The semantics of this API resemble :class:`~collections.namedtuple`. The first
-argument of the call to :class:`Enum` is the name of the enumeration.
-
-The second argument is the *source* of enumeration member names. It can be a
-whitespace-separated string of names, a sequence of names, a sequence of
-2-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to
-values. The last two options enable assigning arbitrary values to
-enumerations; the others auto-assign increasing integers starting with 1 (use
-the ``start`` parameter to specify a different starting value). A
-new class derived from :class:`Enum` is returned. In other words, the above
-assignment to :class:`Animal` is equivalent to::
-
- >>> class Animal(Enum):
- ... ANT = 1
- ... BEE = 2
- ... CAT = 3
- ... DOG = 4
- ...
-
-The reason for defaulting to ``1`` as the starting number and not ``0`` is
-that ``0`` is ``False`` in a boolean sense, but by default enum members all
-evaluate to ``True``.
-
-Pickling enums created with the functional API can be tricky as frame stack
-implementation details are used to try and figure out which module the
-enumeration is being created in (e.g. it will fail if you use a utility
-function in separate module, and also may not work on IronPython or Jython).
-The solution is to specify the module name explicitly as follows::
-
- >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)
-
-.. warning::
-
- If ``module`` is not supplied, and Enum cannot determine what it is,
- the new Enum members will not be unpicklable; to keep errors closer to
- the source, pickling will be disabled.
-
-The new pickle protocol 4 also, in some circumstances, relies on
-:attr:`~definition.__qualname__` being set to the location where pickle will be able
-to find the class. For example, if the class was made available in class
-SomeData in the global scope::
-
- >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal')
-
-The complete signature is::
-
- Enum(
- value='NewEnumName',
- names=<...>,
- *,
- module='...',
- qualname='...',
- type=,
- start=1,
- )
-
-:value: What the new enum class will record as its name.
-
-:names: The enum members. This can be a whitespace or comma separated string
- (values will start at 1 unless otherwise specified)::
-
- 'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'
-
- or an iterator of names::
-
- ['RED', 'GREEN', 'BLUE']
-
- or an iterator of (name, value) pairs::
-
- [('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]
-
- or a mapping::
-
- {'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}
-
-:module: name of module where new enum class can be found.
-
-:qualname: where in module new enum class can be found.
-
-:type: type to mix in to new enum class.
-
-:start: number to start counting at if only names are passed in.
-
-.. versionchanged:: 3.5
- The *start* parameter was added.
-
-
-Derived Enumerations
---------------------
-
-IntEnum
-^^^^^^^
-
-The first variation of :class:`Enum` that is provided is also a subclass of
-:class:`int`. Members of an :class:`IntEnum` can be compared to integers;
-by extension, integer enumerations of different types can also be compared
-to each other::
-
- >>> from enum import IntEnum
- >>> class Shape(IntEnum):
- ... CIRCLE = 1
- ... SQUARE = 2
- ...
- >>> class Request(IntEnum):
- ... POST = 1
- ... GET = 2
- ...
- >>> Shape == 1
- False
- >>> Shape.CIRCLE == 1
- True
- >>> Shape.CIRCLE == Request.POST
- True
-
-However, they still can't be compared to standard :class:`Enum` enumerations::
-
- >>> class Shape(IntEnum):
- ... CIRCLE = 1
- ... SQUARE = 2
- ...
- >>> class Color(Enum):
- ... RED = 1
- ... GREEN = 2
- ...
- >>> Shape.CIRCLE == Color.RED
- False
-
-:class:`IntEnum` values behave like integers in other ways you'd expect::
-
- >>> int(Shape.CIRCLE)
- 1
- >>> ['a', 'b', 'c'][Shape.CIRCLE]
- 'b'
- >>> [i for i in range(Shape.SQUARE)]
- [0, 1]
-
-
-StrEnum
-^^^^^^^
-
-The second variation of :class:`Enum` that is provided is also a subclass of
-:class:`str`. Members of a :class:`StrEnum` can be compared to strings;
-by extension, string enumerations of different types can also be compared
-to each other. :class:`StrEnum` exists to help avoid the problem of getting
-an incorrect member::
-
- >>> from enum import StrEnum
- >>> class Directions(StrEnum):
- ... NORTH = 'north', # notice the trailing comma
- ... SOUTH = 'south'
-
-Before :class:`StrEnum`, ``Directions.NORTH`` would have been the :class:`tuple`
-``('north',)``.
-
-.. versionadded:: 3.10
-
-
-IntFlag
-^^^^^^^
-
-The next variation of :class:`Enum` provided, :class:`IntFlag`, is also based
-on :class:`int`. The difference being :class:`IntFlag` members can be combined
-using the bitwise operators (&, \|, ^, ~) and the result is still an
-:class:`IntFlag` member, if possible. However, as the name implies, :class:`IntFlag`
-members also subclass :class:`int` and can be used wherever an :class:`int` is
-used.
-
-.. note::
-
- Any operation on an :class:`IntFlag` member besides the bit-wise operations will
- lose the :class:`IntFlag` membership.
-
- Bit-wise operations that result in invalid :class:`IntFlag` values will lose the
- :class:`IntFlag` membership. See :class:`FlagBoundary` for
- details.
-
-.. versionadded:: 3.6
-.. versionchanged:: 3.10
-
-Sample :class:`IntFlag` class::
-
- >>> from enum import IntFlag
- >>> class Perm(IntFlag):
- ... R = 4
- ... W = 2
- ... X = 1
- ...
- >>> Perm.R | Perm.W
- Perm.R|Perm.W
- >>> Perm.R + Perm.W
- 6
- >>> RW = Perm.R | Perm.W
- >>> Perm.R in RW
- True
-
-It is also possible to name the combinations::
-
- >>> class Perm(IntFlag):
- ... R = 4
- ... W = 2
- ... X = 1
- ... RWX = 7
- >>> Perm.RWX
- Perm.RWX
- >>> ~Perm.RWX
- Perm(0)
- >>> Perm(7)
- Perm.RWX
-
-.. note::
-
- Named combinations are considered aliases. Aliases do not show up during
- iteration, but can be returned from by-value lookups.
-
-.. versionchanged:: 3.10
-
-Another important difference between :class:`IntFlag` and :class:`Enum` is that
-if no flags are set (the value is 0), its boolean evaluation is :data:`False`::
-
- >>> Perm.R & Perm.X
- Perm(0)
- >>> bool(Perm.R & Perm.X)
- False
-
-Because :class:`IntFlag` members are also subclasses of :class:`int` they can
-be combined with them (but may lose :class:`IntFlag` membership::
-
- >>> Perm.X | 4
- Perm.R|Perm.X
-
- >>> Perm.X | 8
- 9
-
-.. note::
-
- The negation operator, ``~``, always returns an :class:`IntFlag` member with a
- positive value::
-
- >>> (~Perm.X).value == (Perm.R|Perm.W).value == 6
- True
-
-:class:`IntFlag` members can also be iterated over::
-
- >>> list(RW)
- [Perm.R, Perm.W]
-
-.. versionadded:: 3.10
-
-
-Flag
-^^^^
-
-The last variation is :class:`Flag`. Like :class:`IntFlag`, :class:`Flag`
-members can be combined using the bitwise operators (&, \|, ^, ~). Unlike
-:class:`IntFlag`, they cannot be combined with, nor compared against, any
-other :class:`Flag` enumeration, nor :class:`int`. While it is possible to
-specify the values directly it is recommended to use :class:`auto` as the
-value and let :class:`Flag` select an appropriate value.
-
-.. versionadded:: 3.6
-
-Like :class:`IntFlag`, if a combination of :class:`Flag` members results in no
-flags being set, the boolean evaluation is :data:`False`::
-
- >>> from enum import Flag, auto
- >>> class Color(Flag):
- ... RED = auto()
- ... BLUE = auto()
- ... GREEN = auto()
- ...
- >>> Color.RED & Color.GREEN
- Color(0)
- >>> bool(Color.RED & Color.GREEN)
- False
-
-Individual flags should have values that are powers of two (1, 2, 4, 8, ...),
-while combinations of flags won't::
-
- >>> class Color(Flag):
- ... RED = auto()
- ... BLUE = auto()
- ... GREEN = auto()
- ... WHITE = RED | BLUE | GREEN
- ...
- >>> Color.WHITE
- Color.WHITE
-
-Giving a name to the "no flags set" condition does not change its boolean
-value::
-
- >>> class Color(Flag):
- ... BLACK = 0
- ... RED = auto()
- ... BLUE = auto()
- ... GREEN = auto()
- ...
- >>> Color.BLACK
- Color.BLACK
- >>> bool(Color.BLACK)
- False
-
-:class:`Flag` members can also be iterated over::
-
- >>> purple = Color.RED | Color.BLUE
- >>> list(purple)
- [Color.RED, Color.BLUE]
-
-.. versionadded:: 3.10
-
-.. note::
-
- For the majority of new code, :class:`Enum` and :class:`Flag` are strongly
- recommended, since :class:`IntEnum` and :class:`IntFlag` break some
- semantic promises of an enumeration (by being comparable to integers, and
- thus by transitivity to other unrelated enumerations). :class:`IntEnum`
- and :class:`IntFlag` should be used only in cases where :class:`Enum` and
- :class:`Flag` will not do; for example, when integer constants are replaced
- with enumerations, or for interoperability with other systems.
-
-
-Others
-^^^^^^
-
-While :class:`IntEnum` is part of the :mod:`enum` module, it would be very
-simple to implement independently::
-
- class IntEnum(int, Enum):
- pass
-
-This demonstrates how similar derived enumerations can be defined; for example
-a :class:`StrEnum` that mixes in :class:`str` instead of :class:`int`.
-
-Some rules:
-
-1. When subclassing :class:`Enum`, mix-in types must appear before
- :class:`Enum` itself in the sequence of bases, as in the :class:`IntEnum`
- example above.
-2. While :class:`Enum` can have members of any type, once you mix in an
- additional type, all the members must have values of that type, e.g.
- :class:`int` above. This restriction does not apply to mix-ins which only
- add methods and don't specify another type.
-3. When another data type is mixed in, the :attr:`value` attribute is *not the
- same* as the enum member itself, although it is equivalent and will compare
- equal.
-4. %-style formatting: `%s` and `%r` call the :class:`Enum` class's
- :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as
- `%i` or `%h` for IntEnum) treat the enum member as its mixed-in type.
-5. :ref:`Formatted string literals `, :meth:`str.format`,
- and :func:`format` will use the mixed-in type's :meth:`__format__`
- unless :meth:`__str__` or :meth:`__format__` is overridden in the subclass,
- in which case the overridden methods or :class:`Enum` methods will be used.
- Use the !s and !r format codes to force usage of the :class:`Enum` class's
- :meth:`__str__` and :meth:`__repr__` methods.
-
-When to use :meth:`__new__` vs. :meth:`__init__`
-------------------------------------------------
-
-:meth:`__new__` must be used whenever you want to customize the actual value of
-the :class:`Enum` member. Any other modifications may go in either
-:meth:`__new__` or :meth:`__init__`, with :meth:`__init__` being preferred.
-
-For example, if you want to pass several items to the constructor, but only
-want one of them to be the value::
-
- >>> class Coordinate(bytes, Enum):
- ... """
- ... Coordinate with binary codes that can be indexed by the int code.
- ... """
- ... def __new__(cls, value, label, unit):
- ... obj = bytes.__new__(cls, [value])
- ... obj._value_ = value
- ... obj.label = label
- ... obj.unit = unit
- ... return obj
- ... PX = (0, 'P.X', 'km')
- ... PY = (1, 'P.Y', 'km')
- ... VX = (2, 'V.X', 'km/s')
- ... VY = (3, 'V.Y', 'km/s')
- ...
-
- >>> print(Coordinate['PY'])
- PY
-
- >>> print(Coordinate(3))
- VY
-
-
-Finer Points
-^^^^^^^^^^^^
-
-Supported ``__dunder__`` names
-""""""""""""""""""""""""""""""
-
-:attr:`__members__` is a read-only ordered mapping of ``member_name``:``member``
-items. It is only available on the class.
-
-:meth:`__new__`, if specified, must create and return the enum members; it is
-also a very good idea to set the member's :attr:`_value_` appropriately. Once
-all the members are created it is no longer used.
-
-
-Supported ``_sunder_`` names
-""""""""""""""""""""""""""""
-
-- ``_name_`` -- name of the member
-- ``_value_`` -- value of the member; can be set / modified in ``__new__``
-
-- ``_missing_`` -- a lookup function used when a value is not found; may be
- overridden
-- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`,
- that will not be transformed into members, and will be removed from the final
- class
-- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent
- (class attribute, removed during class creation)
-- ``_generate_next_value_`` -- used by the `Functional API`_ and by
- :class:`auto` to get an appropriate value for an enum member; may be
- overridden
-
-.. note::
-
- For standard :class:`Enum` classes the next value chosen is the last value seen
- incremented by one.
-
- For :class:`Flag` classes the next value chosen will be the next highest
- power-of-two, regardless of the last value seen.
-
-.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_``
-.. versionadded:: 3.7 ``_ignore_``
-
-To help keep Python 2 / Python 3 code in sync an :attr:`_order_` attribute can
-be provided. It will be checked against the actual order of the enumeration
-and raise an error if the two do not match::
-
- >>> class Color(Enum):
- ... _order_ = 'RED GREEN BLUE'
- ... RED = 1
- ... BLUE = 3
- ... GREEN = 2
- ...
- Traceback (most recent call last):
- ...
- TypeError: member order does not match _order_:
- ['RED', 'BLUE', 'GREEN']
- ['RED', 'GREEN', 'BLUE']
-
-.. note::
-
- In Python 2 code the :attr:`_order_` attribute is necessary as definition
- order is lost before it can be recorded.
-
-
-_Private__names
-"""""""""""""""
-
-Private names are not converted to enum members, but remain normal attributes.
-
-.. versionchanged:: 3.10
-
-
-``Enum`` member type
-""""""""""""""""""""
-
-Enum members are instances of their enum class, and are normally accessed as
-``EnumClass.member``. In Python versions ``3.5`` to ``3.9`` you could access
-members from other members -- this practice was discouraged, and in ``3.12``
-:class:`Enum` will return to not allowing it, while in ``3.10`` and ``3.11``
-it will raise a :exc:`DeprecationWarning`::
-
- >>> class FieldTypes(Enum):
- ... name = 0
- ... value = 1
- ... size = 2
- ...
- >>> FieldTypes.value.size # doctest: +SKIP
- DeprecationWarning: accessing one member from another is not supported,
- and will be disabled in 3.12
-
-
-.. versionchanged:: 3.5
-.. versionchanged:: 3.10
-
-
-Creating members that are mixed with other data types
-"""""""""""""""""""""""""""""""""""""""""""""""""""""
-
-When subclassing other data types, such as :class:`int` or :class:`str`, with
-an :class:`Enum`, all values after the `=` are passed to that data type's
-constructor. For example::
-
- >>> class MyEnum(IntEnum):
- ... example = '11', 16 # '11' will be interpreted as a hexadecimal
- ... # number
- >>> MyEnum.example.value
- 17
-
-
-Boolean value of ``Enum`` classes and members
-"""""""""""""""""""""""""""""""""""""""""""""
-
-Enum classes that are mixed with non-:class:`Enum` types (such as
-:class:`int`, :class:`str`, etc.) are evaluated according to the mixed-in
-type's rules; otherwise, all members evaluate as :data:`True`. To make your
-own enum's boolean evaluation depend on the member's value add the following to
-your class::
-
- def __bool__(self):
- return bool(self.value)
-
-Plain :class:`Enum` classes always evaluate as :data:`True`.
-
-
-``Enum`` classes with methods
-"""""""""""""""""""""""""""""
-
-If you give your enum subclass extra methods, like the `Planet`_
-class above, those methods will show up in a :func:`dir` of the member,
-but not of the class::
-
- >>> dir(Planet)
- ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS', 'VENUS', '__class__', '__doc__', '__members__', '__module__']
- >>> dir(Planet.EARTH)
- ['__class__', '__doc__', '__module__', 'mass', 'name', 'radius', 'surface_gravity', 'value']
-
-
-Combining members of ``Flag``
-"""""""""""""""""""""""""""""
-
-Iterating over a combination of :class:`Flag` members will only return the members that
-are comprised of a single bit::
-
- >>> class Color(Flag):
- ... RED = auto()
- ... GREEN = auto()
- ... BLUE = auto()
- ... MAGENTA = RED | BLUE
- ... YELLOW = RED | GREEN
- ... CYAN = GREEN | BLUE
- ...
- >>> Color(3) # named combination
- Color.YELLOW
- >>> Color(7) # not named combination
- Color.RED|Color.GREEN|Color.BLUE
-
-``StrEnum`` and :meth:`str.__str__`
-"""""""""""""""""""""""""""""""""""
-
-An important difference between :class:`StrEnum` and other Enums is the
-:meth:`__str__` method; because :class:`StrEnum` members are strings, some
-parts of Python will read the string data directly, while others will call
-:meth:`str()`. To make those two operations have the same result,
-:meth:`StrEnum.__str__` will be the same as :meth:`str.__str__` so that
-``str(StrEnum.member) == StrEnum.member`` is true.
-
-``Flag`` and ``IntFlag`` minutia
-""""""""""""""""""""""""""""""""
-
-Using the following snippet for our examples::
-
- >>> class Color(IntFlag):
- ... BLACK = 0
- ... RED = 1
- ... GREEN = 2
- ... BLUE = 4
- ... PURPLE = RED | BLUE
- ... WHITE = RED | GREEN | BLUE
- ...
-
-the following are true:
-
-- single-bit flags are canonical
-- multi-bit and zero-bit flags are aliases
-- only canonical flags are returned during iteration::
-
- >>> list(Color.WHITE)
- [Color.RED, Color.GREEN, Color.BLUE]
-
-- negating a flag or flag set returns a new flag/flag set with the
- corresponding positive integer value::
-
- >>> Color.BLUE
- Color.BLUE
-
- >>> ~Color.BLUE
- Color.RED|Color.GREEN
-
-- names of pseudo-flags are constructed from their members' names::
-
- >>> (Color.RED | Color.GREEN).name
- 'RED|GREEN'
-
-- multi-bit flags, aka aliases, can be returned from operations::
-
- >>> Color.RED | Color.BLUE
- Color.PURPLE
-
- >>> Color(7) # or Color(-1)
- Color.WHITE
-
- >>> Color(0)
- Color.BLACK
-
-- membership / containment checking has changed slightly -- zero valued flags
- are never considered to be contained::
-
- >>> Color.BLACK in Color.WHITE
- False
-
- otherwise, if all bits of one flag are in the other flag, True is returned::
-
- >>> Color.PURPLE in Color.WHITE
- True
-
-There is a new boundary mechanism that controls how out-of-range / invalid
-bits are handled: ``STRICT``, ``CONFORM``, ``EJECT``, and ``KEEP``:
-
- * STRICT --> raises an exception when presented with invalid values
- * CONFORM --> discards any invalid bits
- * EJECT --> lose Flag status and become a normal int with the given value
- * KEEP --> keep the extra bits
- - keeps Flag status and extra bits
- - extra bits do not show up in iteration
- - extra bits do show up in repr() and str()
-
-The default for Flag is ``STRICT``, the default for ``IntFlag`` is ``EJECT``,
-and the default for ``_convert_`` is ``KEEP`` (see ``ssl.Options`` for an
-example of when ``KEEP`` is needed).
-
-
-.. _enum-class-differences:
-
-How are Enums different?
-------------------------
-
-Enums have a custom metaclass that affects many aspects of both derived :class:`Enum`
-classes and their instances (members).
-
-
-Enum Classes
-^^^^^^^^^^^^
-
-The :class:`EnumType` metaclass is responsible for providing the
-:meth:`__contains__`, :meth:`__dir__`, :meth:`__iter__` and other methods that
-allow one to do things with an :class:`Enum` class that fail on a typical
-class, such as `list(Color)` or `some_enum_var in Color`. :class:`EnumType` is
-responsible for ensuring that various other methods on the final :class:`Enum`
-class are correct (such as :meth:`__new__`, :meth:`__getnewargs__`,
-:meth:`__str__` and :meth:`__repr__`).
-
-
-Enum Members (aka instances)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The most interesting thing about enum members is that they are singletons.
-:class:`EnumType` creates them all while it is creating the enum class itself,
-and then puts a custom :meth:`__new__` in place to ensure that no new ones are
-ever instantiated by returning only the existing member instances.
-
-
-.. _enum-cookbook:
-
-
-While :class:`Enum`, :class:`IntEnum`, :class:`StrEnum`, :class:`Flag`, and
-:class:`IntFlag` are expected to cover the majority of use-cases, they cannot
-cover them all. Here are recipes for some different types of enumerations
-that can be used directly, or as examples for creating one's own.
-
-
-Omitting values
-^^^^^^^^^^^^^^^
-
-In many use-cases one doesn't care what the actual value of an enumeration
-is. There are several ways to define this type of simple enumeration:
-
-- use instances of :class:`auto` for the value
-- use instances of :class:`object` as the value
-- use a descriptive string as the value
-- use a tuple as the value and a custom :meth:`__new__` to replace the
- tuple with an :class:`int` value
-
-Using any of these methods signifies to the user that these values are not
-important, and also enables one to add, remove, or reorder members without
-having to renumber the remaining members.
-
-
-Using :class:`auto`
-"""""""""""""""""""
-
-Using :class:`auto` would look like::
-
- >>> class Color(Enum):
- ... RED = auto()
- ... BLUE = auto()
- ... GREEN = auto()
- ...
- >>> Color.GREEN
-
-
-
-Using :class:`object`
-"""""""""""""""""""""
-
-Using :class:`object` would look like::
-
- >>> class Color(Enum):
- ... RED = object()
- ... GREEN = object()
- ... BLUE = object()
- ...
- >>> Color.GREEN
-
-
-
-Using a descriptive string
-""""""""""""""""""""""""""
-
-Using a string as the value would look like::
-
- >>> class Color(Enum):
- ... RED = 'stop'
- ... GREEN = 'go'
- ... BLUE = 'too fast!'
- ...
- >>> Color.GREEN
-
- >>> Color.GREEN.value
- 'go'
-
-
-Using a custom :meth:`__new__`
-""""""""""""""""""""""""""""""
-
-Using an auto-numbering :meth:`__new__` would look like::
-
- >>> class AutoNumber(Enum):
- ... def __new__(cls):
- ... value = len(cls.__members__) + 1
- ... obj = object.__new__(cls)
- ... obj._value_ = value
- ... return obj
- ...
- >>> class Color(AutoNumber):
- ... RED = ()
- ... GREEN = ()
- ... BLUE = ()
- ...
- >>> Color.GREEN
-
- >>> Color.GREEN.value
- 2
-
-To make a more general purpose ``AutoNumber``, add ``*args`` to the signature::
-
- >>> class AutoNumber(Enum):
- ... def __new__(cls, *args): # this is the only change from above
- ... value = len(cls.__members__) + 1
- ... obj = object.__new__(cls)
- ... obj._value_ = value
- ... return obj
- ...
-
-Then when you inherit from ``AutoNumber`` you can write your own ``__init__``
-to handle any extra arguments::
-
- >>> class Swatch(AutoNumber):
- ... def __init__(self, pantone='unknown'):
- ... self.pantone = pantone
- ... AUBURN = '3497'
- ... SEA_GREEN = '1246'
- ... BLEACHED_CORAL = () # New color, no Pantone code yet!
- ...
- >>> Swatch.SEA_GREEN
-
- >>> Swatch.SEA_GREEN.pantone
- '1246'
- >>> Swatch.BLEACHED_CORAL.pantone
- 'unknown'
-
-.. note::
-
- The :meth:`__new__` method, if defined, is used during creation of the Enum
- members; it is then replaced by Enum's :meth:`__new__` which is used after
- class creation for lookup of existing members.
-
-
-OrderedEnum
-^^^^^^^^^^^
-
-An ordered enumeration that is not based on :class:`IntEnum` and so maintains
-the normal :class:`Enum` invariants (such as not being comparable to other
-enumerations)::
-
- >>> class OrderedEnum(Enum):
- ... def __ge__(self, other):
- ... if self.__class__ is other.__class__:
- ... return self.value >= other.value
- ... return NotImplemented
- ... def __gt__(self, other):
- ... if self.__class__ is other.__class__:
- ... return self.value > other.value
- ... return NotImplemented
- ... def __le__(self, other):
- ... if self.__class__ is other.__class__:
- ... return self.value <= other.value
- ... return NotImplemented
- ... def __lt__(self, other):
- ... if self.__class__ is other.__class__:
- ... return self.value < other.value
- ... return NotImplemented
- ...
- >>> class Grade(OrderedEnum):
- ... A = 5
- ... B = 4
- ... C = 3
- ... D = 2
- ... F = 1
- ...
- >>> Grade.C < Grade.A
- True
-
-
-DuplicateFreeEnum
-^^^^^^^^^^^^^^^^^
-
-Raises an error if a duplicate member name is found instead of creating an
-alias::
-
- >>> class DuplicateFreeEnum(Enum):
- ... def __init__(self, *args):
- ... cls = self.__class__
- ... if any(self.value == e.value for e in cls):
- ... a = self.name
- ... e = cls(self.value).name
- ... raise ValueError(
- ... "aliases not allowed in DuplicateFreeEnum: %r --> %r"
- ... % (a, e))
- ...
- >>> class Color(DuplicateFreeEnum):
- ... RED = 1
- ... GREEN = 2
- ... BLUE = 3
- ... GRENE = 2
- ...
- Traceback (most recent call last):
- ...
- ValueError: aliases not allowed in DuplicateFreeEnum: 'GRENE' --> 'GREEN'
-
-.. note::
-
- This is a useful example for subclassing Enum to add or change other
- behaviors as well as disallowing aliases. If the only desired change is
- disallowing aliases, the :func:`unique` decorator can be used instead.
-
-
-Planet
-^^^^^^
-
-If :meth:`__new__` or :meth:`__init__` is defined the value of the enum member
-will be passed to those methods::
-
- >>> class Planet(Enum):
- ... MERCURY = (3.303e+23, 2.4397e6)
- ... VENUS = (4.869e+24, 6.0518e6)
- ... EARTH = (5.976e+24, 6.37814e6)
- ... MARS = (6.421e+23, 3.3972e6)
- ... JUPITER = (1.9e+27, 7.1492e7)
- ... SATURN = (5.688e+26, 6.0268e7)
- ... URANUS = (8.686e+25, 2.5559e7)
- ... NEPTUNE = (1.024e+26, 2.4746e7)
- ... def __init__(self, mass, radius):
- ... self.mass = mass # in kilograms
- ... self.radius = radius # in meters
- ... @property
- ... def surface_gravity(self):
- ... # universal gravitational constant (m3 kg-1 s-2)
- ... G = 6.67300E-11
- ... return G * self.mass / (self.radius * self.radius)
- ...
- >>> Planet.EARTH.value
- (5.976e+24, 6378140.0)
- >>> Planet.EARTH.surface_gravity
- 9.802652743337129
-
-.. _enum-time-period:
-
-TimePeriod
-^^^^^^^^^^
-
-An example to show the :attr:`_ignore_` attribute in use::
-
- >>> from datetime import timedelta
- >>> class Period(timedelta, Enum):
- ... "different lengths of time"
- ... _ignore_ = 'Period i'
- ... Period = vars()
- ... for i in range(367):
- ... Period['day_%d' % i] = i
- ...
- >>> list(Period)[:2]
- [Period.day_0, Period.day_1]
- >>> list(Period)[-2:]
- [Period.day_365, Period.day_366]
-
-
-Conforming input to Flag
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-Creating a :class:`Flag` enum that is more resilient out-of-bounds results to
-mathematical operations, you can use the :attr:`FlagBoundary.CONFORM` setting::
-
- >>> from enum import Flag, CONFORM, auto
- >>> class Weekday(Flag, boundary=CONFORM):
- ... MONDAY = auto()
- ... TUESDAY = auto()
- ... WEDNESDAY = auto()
- ... THURSDAY = auto()
- ... FRIDAY = auto()
- ... SATURDAY = auto()
- ... SUNDAY = auto()
- >>> today = Weekday.TUESDAY
- >>> Weekday(today + 22) # what day is three weeks from tomorrow?
- >>> Weekday.WEDNESDAY
-
-
-.. _enumtype-examples:
-
-Subclassing EnumType
---------------------
-
-While most enum needs can be met by customizing :class:`Enum` subclasses,
-either with class decorators or custom functions, :class:`EnumType` can be
-subclassed to provide a different Enum experience.
-
diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst
index 74e861480d2ff8..fb561a6a10b661 100644
--- a/Doc/howto/functional.rst
+++ b/Doc/howto/functional.rst
@@ -65,11 +65,10 @@ output must only depend on its input.
Some languages are very strict about purity and don't even have assignment
statements such as ``a=3`` or ``c = a + b``, but it's difficult to avoid all
-side effects. Printing to the screen or writing to a disk file are side
-effects, for example. For example, in Python a call to the :func:`print` or
-:func:`time.sleep` function both return no useful value; they're only called for
-their side effects of sending some text to the screen or pausing execution for a
-second.
+side effects, such as printing to the screen or writing to a disk file. Another
+example is a call to the :func:`print` or :func:`time.sleep` function, neither
+of which returns a useful value. Both are called only for their side effects
+of sending some text to the screen or pausing execution for a second.
Python programs written in functional style usually won't go to the extreme of
avoiding all I/O or all assignments; instead, they'll provide a
@@ -316,9 +315,15 @@ line of a file like this::
Sets can take their contents from an iterable and let you iterate over the set's
elements::
- S = {2, 3, 5, 7, 11, 13}
- for i in S:
- print(i)
+ >>> S = {2, 3, 5, 7, 11, 13}
+ >>> for i in S:
+ ... print(i)
+ 2
+ 3
+ 5
+ 7
+ 11
+ 13
@@ -336,18 +341,18 @@ List comprehensions and generator expressions (short form: "listcomps" and
functional programming language Haskell (https://www.haskell.org/). You can strip
all the whitespace from a stream of strings with the following code::
- line_list = [' line 1\n', 'line 2 \n', ...]
+ >>> line_list = [' line 1\n', 'line 2 \n', ' \n', '']
- # Generator expression -- returns iterator
- stripped_iter = (line.strip() for line in line_list)
+ >>> # Generator expression -- returns iterator
+ >>> stripped_iter = (line.strip() for line in line_list)
- # List comprehension -- returns list
- stripped_list = [line.strip() for line in line_list]
+ >>> # List comprehension -- returns list
+ >>> stripped_list = [line.strip() for line in line_list]
You can select only certain elements by adding an ``"if"`` condition::
- stripped_list = [line.strip() for line in line_list
- if line != ""]
+ >>> stripped_list = [line.strip() for line in line_list
+ ... if line != ""]
With a list comprehension, you get back a Python list; ``stripped_list`` is a
list containing the resulting lines, not an iterator. Generator expressions
@@ -364,7 +369,8 @@ have the form::
if condition1
for expr2 in sequence2
if condition2
- for expr3 in sequence3 ...
+ for expr3 in sequence3
+ ...
if condition3
for exprN in sequenceN
if conditionN )
@@ -590,7 +596,7 @@ generator function.
In addition to :meth:`~generator.send`, there are two other methods on
generators:
-* :meth:`throw(type, value=None, traceback=None) ` is used to
+* :meth:`throw(value) ` is used to
raise an exception inside the generator; the exception is raised by the
``yield`` expression where the generator's execution is paused.
diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst
index eae8f143ee206f..01a78a556591c9 100644
--- a/Doc/howto/index.rst
+++ b/Doc/howto/index.rst
@@ -17,7 +17,6 @@ Currently, the HOWTOs are:
cporting.rst
curses.rst
descriptor.rst
- enum.rst
functional.rst
logging.rst
logging-cookbook.rst
diff --git a/Doc/howto/ipaddress.rst b/Doc/howto/ipaddress.rst
index 452e3671060a5e..e852db98156fac 100644
--- a/Doc/howto/ipaddress.rst
+++ b/Doc/howto/ipaddress.rst
@@ -32,7 +32,7 @@ A Note on IP Versions
---------------------
For readers that aren't particularly familiar with IP addressing, it's
-important to know that the Internet Protocol is currently in the process
+important to know that the Internet Protocol (IP) is currently in the process
of moving from version 4 of the protocol to version 6. This transition is
occurring largely because version 4 of the protocol doesn't provide enough
addresses to handle the needs of the whole world, especially given the
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 5777a4c5031f85..7f4fe3a63a7026 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -7,7 +7,8 @@ Logging Cookbook
:Author: Vinay Sajip
This page contains a number of recipes related to logging, which have been found
-useful in the past.
+useful in the past. For links to tutorial and reference information, please see
+:ref:`cookbook-ref-links`.
.. currentmodule:: logging
@@ -332,7 +333,7 @@ Dealing with handlers that block
.. currentmodule:: logging.handlers
Sometimes you have to get your logging handlers to do their work without
-blocking the thread you're logging from. This is common in Web applications,
+blocking the thread you're logging from. This is common in web applications,
though of course it also occurs in other scenarios.
A common culprit which demonstrates sluggish behaviour is the
@@ -541,6 +542,17 @@ alternative there, as well as adapting the above script to use your alternative
serialization.
+Running a logging socket listener in production
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To run a logging listener in production, you may need to use a process-management tool
+such as `Supervisor `_. `Here
+`_ is a Gist which
+provides the bare-bones files to run the above functionality using Supervisor: you
+will need to change the `/path/to/` parts in the Gist to reflect the actual paths you
+want to use.
+
+
.. _context-info:
Adding contextual information to your logging output
@@ -702,6 +714,254 @@ which, when run, produces something like:
2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters
2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters
+Use of ``contextvars``
+----------------------
+
+Since Python 3.7, the :mod:`contextvars` module has provided context-local storage
+which works for both :mod:`threading` and :mod:`asyncio` processing needs. This type
+of storage may thus be generally preferable to thread-locals. The following example
+shows how, in a multi-threaded environment, logs can populated with contextual
+information such as, for example, request attributes handled by web applications.
+
+For the purposes of illustration, say that you have different web applications, each
+independent of the other but running in the same Python process and using a library
+common to them. How can each of these applications have their own log, where all
+logging messages from the library (and other request processing code) are directed to
+the appropriate application's log file, while including in the log additional
+contextual information such as client IP, HTTP request method and client username?
+
+Let's assume that the library can be simulated by the following code:
+
+.. code-block:: python
+
+ # webapplib.py
+ import logging
+ import time
+
+ logger = logging.getLogger(__name__)
+
+ def useful():
+ # Just a representative event logged from the library
+ logger.debug('Hello from webapplib!')
+ # Just sleep for a bit so other threads get to run
+ time.sleep(0.01)
+
+We can simulate the multiple web applications by means of two simple classes,
+``Request`` and ``WebApp``. These simulate how real threaded web applications work -
+each request is handled by a thread:
+
+.. code-block:: python
+
+ # main.py
+ import argparse
+ from contextvars import ContextVar
+ import logging
+ import os
+ from random import choice
+ import threading
+ import webapplib
+
+ logger = logging.getLogger(__name__)
+ root = logging.getLogger()
+ root.setLevel(logging.DEBUG)
+
+ class Request:
+ """
+ A simple dummy request class which just holds dummy HTTP request method,
+ client IP address and client username
+ """
+ def __init__(self, method, ip, user):
+ self.method = method
+ self.ip = ip
+ self.user = user
+
+ # A dummy set of requests which will be used in the simulation - we'll just pick
+ # from this list randomly. Note that all GET requests are from 192.168.2.XXX
+ # addresses, whereas POST requests are from 192.16.3.XXX addresses. Three users
+ # are represented in the sample requests.
+
+ REQUESTS = [
+ Request('GET', '192.168.2.20', 'jim'),
+ Request('POST', '192.168.3.20', 'fred'),
+ Request('GET', '192.168.2.21', 'sheila'),
+ Request('POST', '192.168.3.21', 'jim'),
+ Request('GET', '192.168.2.22', 'fred'),
+ Request('POST', '192.168.3.22', 'sheila'),
+ ]
+
+ # Note that the format string includes references to request context information
+ # such as HTTP method, client IP and username
+
+ formatter = logging.Formatter('%(threadName)-11s %(appName)s %(name)-9s %(user)-6s %(ip)s %(method)-4s %(message)s')
+
+ # Create our context variables. These will be filled at the start of request
+ # processing, and used in the logging that happens during that processing
+
+ ctx_request = ContextVar('request')
+ ctx_appname = ContextVar('appname')
+
+ class InjectingFilter(logging.Filter):
+ """
+ A filter which injects context-specific information into logs and ensures
+ that only information for a specific webapp is included in its log
+ """
+ def __init__(self, app):
+ self.app = app
+
+ def filter(self, record):
+ request = ctx_request.get()
+ record.method = request.method
+ record.ip = request.ip
+ record.user = request.user
+ record.appName = appName = ctx_appname.get()
+ return appName == self.app.name
+
+ class WebApp:
+ """
+ A dummy web application class which has its own handler and filter for a
+ webapp-specific log.
+ """
+ def __init__(self, name):
+ self.name = name
+ handler = logging.FileHandler(name + '.log', 'w')
+ f = InjectingFilter(self)
+ handler.setFormatter(formatter)
+ handler.addFilter(f)
+ root.addHandler(handler)
+ self.num_requests = 0
+
+ def process_request(self, request):
+ """
+ This is the dummy method for processing a request. It's called on a
+ different thread for every request. We store the context information into
+ the context vars before doing anything else.
+ """
+ ctx_request.set(request)
+ ctx_appname.set(self.name)
+ self.num_requests += 1
+ logger.debug('Request processing started')
+ webapplib.useful()
+ logger.debug('Request processing finished')
+
+ def main():
+ fn = os.path.splitext(os.path.basename(__file__))[0]
+ adhf = argparse.ArgumentDefaultsHelpFormatter
+ ap = argparse.ArgumentParser(formatter_class=adhf, prog=fn,
+ description='Simulate a couple of web '
+ 'applications handling some '
+ 'requests, showing how request '
+ 'context can be used to '
+ 'populate logs')
+ aa = ap.add_argument
+ aa('--count', '-c', default=100, help='How many requests to simulate')
+ options = ap.parse_args()
+
+ # Create the dummy webapps and put them in a list which we can use to select
+ # from randomly
+ app1 = WebApp('app1')
+ app2 = WebApp('app2')
+ apps = [app1, app2]
+ threads = []
+ # Add a common handler which will capture all events
+ handler = logging.FileHandler('app.log', 'w')
+ handler.setFormatter(formatter)
+ root.addHandler(handler)
+
+ # Generate calls to process requests
+ for i in range(options.count):
+ try:
+ # Pick an app at random and a request for it to process
+ app = choice(apps)
+ request = choice(REQUESTS)
+ # Process the request in its own thread
+ t = threading.Thread(target=app.process_request, args=(request,))
+ threads.append(t)
+ t.start()
+ except KeyboardInterrupt:
+ break
+
+ # Wait for the threads to terminate
+ for t in threads:
+ t.join()
+
+ for app in apps:
+ print('%s processed %s requests' % (app.name, app.num_requests))
+
+ if __name__ == '__main__':
+ main()
+
+If you run the above, you should find that roughly half the requests go
+into :file:`app1.log` and the rest into :file:`app2.log`, and the all the requests are
+logged to :file:`app.log`. Each webapp-specific log will contain only log entries for
+only that webapp, and the request information will be displayed consistently in the
+log (i.e. the information in each dummy request will always appear together in a log
+line). This is illustrated by the following shell output:
+
+.. code-block:: shell
+
+ ~/logging-contextual-webapp$ python main.py
+ app1 processed 51 requests
+ app2 processed 49 requests
+ ~/logging-contextual-webapp$ wc -l *.log
+ 153 app1.log
+ 147 app2.log
+ 300 app.log
+ 600 total
+ ~/logging-contextual-webapp$ head -3 app1.log
+ Thread-3 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started
+ Thread-3 (process_request) app1 webapplib jim 192.168.3.21 POST Hello from webapplib!
+ Thread-5 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started
+ ~/logging-contextual-webapp$ head -3 app2.log
+ Thread-1 (process_request) app2 __main__ sheila 192.168.2.21 GET Request processing started
+ Thread-1 (process_request) app2 webapplib sheila 192.168.2.21 GET Hello from webapplib!
+ Thread-2 (process_request) app2 __main__ jim 192.168.2.20 GET Request processing started
+ ~/logging-contextual-webapp$ head app.log
+ Thread-1 (process_request) app2 __main__ sheila 192.168.2.21 GET Request processing started
+ Thread-1 (process_request) app2 webapplib sheila 192.168.2.21 GET Hello from webapplib!
+ Thread-2 (process_request) app2 __main__ jim 192.168.2.20 GET Request processing started
+ Thread-3 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started
+ Thread-2 (process_request) app2 webapplib jim 192.168.2.20 GET Hello from webapplib!
+ Thread-3 (process_request) app1 webapplib jim 192.168.3.21 POST Hello from webapplib!
+ Thread-4 (process_request) app2 __main__ fred 192.168.2.22 GET Request processing started
+ Thread-5 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started
+ Thread-4 (process_request) app2 webapplib fred 192.168.2.22 GET Hello from webapplib!
+ Thread-6 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started
+ ~/logging-contextual-webapp$ grep app1 app1.log | wc -l
+ 153
+ ~/logging-contextual-webapp$ grep app2 app2.log | wc -l
+ 147
+ ~/logging-contextual-webapp$ grep app1 app.log | wc -l
+ 153
+ ~/logging-contextual-webapp$ grep app2 app.log | wc -l
+ 147
+
+
+Imparting contextual information in handlers
+--------------------------------------------
+
+Each :class:`~Handler` has its own chain of filters.
+If you want to add contextual information to a :class:`LogRecord` without leaking
+it to other handlers, you can use a filter that returns
+a new :class:`~LogRecord` instead of modifying it in-place, as shown in the following script::
+
+ import copy
+ import logging
+
+ def filter(record: logging.LogRecord):
+ record = copy.copy(record)
+ record.user = 'jim'
+ return record
+
+ if __name__ == '__main__':
+ logger = logging.getLogger()
+ logger.setLevel(logging.INFO)
+ handler = logging.StreamHandler()
+ formatter = logging.Formatter('%(message)s from %(user)-8s')
+ handler.setFormatter(formatter)
+ handler.addFilter(filter)
+ logger.addHandler(handler)
+
+ logger.info('A log message')
.. _multiple-processes:
@@ -982,6 +1242,17 @@ to this (remembering to first import :mod:`concurrent.futures`)::
for i in range(10):
executor.submit(worker_process, queue, worker_configurer)
+Deploying Web applications using Gunicorn and uWSGI
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When deploying Web applications using `Gunicorn `_ or `uWSGI
+`_ (or similar), multiple worker
+processes are created to handle client requests. In such environments, avoid creating
+file-based handlers directly in your web application. Instead, use a
+:class:`SocketHandler` to log from the web application to a listener in a separate
+process. This can be set up using a process management tool such as Supervisor - see
+`Running a logging socket listener in production`_ for more details.
+
Using file rotation
-------------------
@@ -1766,22 +2037,15 @@ Python used.
If you need more specialised processing, you can use a custom JSON encoder,
as in the following complete example::
- from __future__ import unicode_literals
-
import json
import logging
- # This next bit is to ensure the script runs unchanged on 2.x and 3.x
- try:
- unicode
- except NameError:
- unicode = str
class Encoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, set):
return tuple(o)
- elif isinstance(o, unicode):
+ elif isinstance(o, str):
return o.encode('unicode_escape').decode('ascii')
return super().default(o)
@@ -2979,3 +3243,193 @@ refer to the comments in the code snippet for more detailed information.
if __name__=='__main__':
main()
+
+Logging to syslog with RFC5424 support
+--------------------------------------
+
+Although :rfc:`5424` dates from 2009, most syslog servers are configured by detault to
+use the older :rfc:`3164`, which hails from 2001. When ``logging`` was added to Python
+in 2003, it supported the earlier (and only existing) protocol at the time. Since
+RFC5424 came out, as there has not been widespread deployment of it in syslog
+servers, the :class:`~logging.handlers.SysLogHandler` functionality has not been
+updated.
+
+RFC 5424 contains some useful features such as support for structured data, and if you
+need to be able to log to a syslog server with support for it, you can do so with a
+subclassed handler which looks something like this::
+
+ import datetime
+ import logging.handlers
+ import re
+ import socket
+ import time
+
+ class SysLogHandler5424(logging.handlers.SysLogHandler):
+
+ tz_offset = re.compile(r'([+-]\d{2})(\d{2})$')
+ escaped = re.compile(r'([\]"\\])')
+
+ def __init__(self, *args, **kwargs):
+ self.msgid = kwargs.pop('msgid', None)
+ self.appname = kwargs.pop('appname', None)
+ super().__init__(*args, **kwargs)
+
+ def format(self, record):
+ version = 1
+ asctime = datetime.datetime.fromtimestamp(record.created).isoformat()
+ m = self.tz_offset.match(time.strftime('%z'))
+ has_offset = False
+ if m and time.timezone:
+ hrs, mins = m.groups()
+ if int(hrs) or int(mins):
+ has_offset = True
+ if not has_offset:
+ asctime += 'Z'
+ else:
+ asctime += f'{hrs}:{mins}'
+ try:
+ hostname = socket.gethostname()
+ except Exception:
+ hostname = '-'
+ appname = self.appname or '-'
+ procid = record.process
+ msgid = '-'
+ msg = super().format(record)
+ sdata = '-'
+ if hasattr(record, 'structured_data'):
+ sd = record.structured_data
+ # This should be a dict where the keys are SD-ID and the value is a
+ # dict mapping PARAM-NAME to PARAM-VALUE (refer to the RFC for what these
+ # mean)
+ # There's no error checking here - it's purely for illustration, and you
+ # can adapt this code for use in production environments
+ parts = []
+
+ def replacer(m):
+ g = m.groups()
+ return '\\' + g[0]
+
+ for sdid, dv in sd.items():
+ part = f'[{sdid}'
+ for k, v in dv.items():
+ s = str(v)
+ s = self.escaped.sub(replacer, s)
+ part += f' {k}="{s}"'
+ part += ']'
+ parts.append(part)
+ sdata = ''.join(parts)
+ return f'{version} {asctime} {hostname} {appname} {procid} {msgid} {sdata} {msg}'
+
+You'll need to be familiar with RFC 5424 to fully understand the above code, and it
+may be that you have slightly different needs (e.g. for how you pass structural data
+to the log). Nevertheless, the above should be adaptable to your speciric needs. With
+the above handler, you'd pass structured data using something like this::
+
+ sd = {
+ 'foo@12345': {'bar': 'baz', 'baz': 'bozz', 'fizz': r'buzz'},
+ 'foo@54321': {'rab': 'baz', 'zab': 'bozz', 'zzif': r'buzz'}
+ }
+ extra = {'structured_data': sd}
+ i = 1
+ logger.debug('Message %d', i, extra=extra)
+
+
+.. patterns-to-avoid:
+
+Patterns to avoid
+-----------------
+
+Although the preceding sections have described ways of doing things you might
+need to do or deal with, it is worth mentioning some usage patterns which are
+*unhelpful*, and which should therefore be avoided in most cases. The following
+sections are in no particular order.
+
+
+Opening the same log file multiple times
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+On Windows, you will generally not be able to open the same file multiple times
+as this will lead to a "file is in use by another process" error. However, on
+POSIX platforms you'll not get any errors if you open the same file multiple
+times. This could be done accidentally, for example by:
+
+* Adding a file handler more than once which references the same file (e.g. by
+ a copy/paste/forget-to-change error).
+
+* Opening two files that look different, as they have different names, but are
+ the same because one is a symbolic link to the other.
+
+* Forking a process, following which both parent and child have a reference to
+ the same file. This might be through use of the :mod:`multiprocessing` module,
+ for example.
+
+Opening a file multiple times might *appear* to work most of the time, but can
+lead to a number of problems in practice:
+
+* Logging output can be garbled because multiple threads or processes try to
+ write to the same file. Although logging guards against concurrent use of the
+ same handler instance by multiple threads, there is no such protection if
+ concurrent writes are attempted by two different threads using two different
+ handler instances which happen to point to the same file.
+
+* An attempt to delete a file (e.g. during file rotation) silently fails,
+ because there is another reference pointing to it. This can lead to confusion
+ and wasted debugging time - log entries end up in unexpected places, or are
+ lost altogether. Or a file that was supposed to be moved remains in place,
+ and grows in size unexpectedly despite size-based rotation being supposedly
+ in place.
+
+Use the techniques outlined in :ref:`multiple-processes` to circumvent such
+issues.
+
+Using loggers as attributes in a class or passing them as parameters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+While there might be unusual cases where you'll need to do this, in general
+there is no point because loggers are singletons. Code can always access a
+given logger instance by name using ``logging.getLogger(name)``, so passing
+instances around and holding them as instance attributes is pointless. Note
+that in other languages such as Java and C#, loggers are often static class
+attributes. However, this pattern doesn't make sense in Python, where the
+module (and not the class) is the unit of software decomposition.
+
+
+Adding handlers other than :class:`NullHandler` to a logger in a library
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Configuring logging by adding handlers, formatters and filters is the
+responsibility of the application developer, not the library developer. If you
+are maintaining a library, ensure that you don't add handlers to any of your
+loggers other than a :class:`~logging.NullHandler` instance.
+
+
+Creating a lot of loggers
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Loggers are singletons that are never freed during a script execution, and so
+creating lots of loggers will use up memory which can't then be freed. Rather
+than create a logger per e.g. file processed or network connection made, use
+the :ref:`existing mechanisms ` for passing contextual
+information into your logs and restrict the loggers created to those describing
+areas within your application (generally modules, but occasionally slightly
+more fine-grained than that).
+
+.. _cookbook-ref-links:
+
+Other resources
+---------------
+
+.. seealso::
+
+ Module :mod:`logging`
+ API reference for the logging module.
+
+ Module :mod:`logging.config`
+ Configuration API for the logging module.
+
+ Module :mod:`logging.handlers`
+ Useful handlers included with the logging module.
+
+ :ref:`Basic Tutorial `
+
+ :ref:`Advanced Tutorial `
diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst
index fcc6bec7688002..ff4e1d73a96531 100644
--- a/Doc/howto/logging.rst
+++ b/Doc/howto/logging.rst
@@ -178,10 +178,11 @@ following example::
raise ValueError('Invalid log level: %s' % loglevel)
logging.basicConfig(level=numeric_level, ...)
-The call to :func:`basicConfig` should come *before* any calls to :func:`debug`,
-:func:`info` etc. As it's intended as a one-off simple configuration facility,
-only the first call will actually do anything: subsequent calls are effectively
-no-ops.
+The call to :func:`basicConfig` should come *before* any calls to
+:func:`debug`, :func:`info`, etc. Otherwise, those functions will call
+:func:`basicConfig` for you with the default options. As it's intended as a
+one-off simple configuration facility, only the first call will actually do
+anything: subsequent calls are effectively no-ops.
If you run the above script several times, the messages from successive runs
are appended to the file *example.log*. If you want each run to start afresh,
diff --git a/Doc/howto/logging_flow.png b/Doc/howto/logging_flow.png
index fac4acd7755302..d65e597f811db5 100644
Binary files a/Doc/howto/logging_flow.png and b/Doc/howto/logging_flow.png differ
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
index 1543823c104c28..abcc34287e3d29 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -20,8 +20,8 @@ Porting Python 2 Code to Python 3
came into existence, you can read Nick Coghlan's `Python 3 Q & A`_ or
Brett Cannon's `Why Python 3 exists`_.
- For help with porting, you can email the python-porting_ mailing list with
- questions.
+
+ For help with porting, you can view the archived python-porting_ mailing list.
The Short Explanation
=====================
@@ -446,7 +446,7 @@ to make sure everything functions as expected in both versions of Python.
.. _pytype: https://github.com/google/pytype
.. _python-future: http://python-future.org/
-.. _python-porting: https://mail.python.org/mailman/listinfo/python-porting
+.. _python-porting: https://mail.python.org/pipermail/python-porting/
.. _six: https://pypi.org/project/six
.. _tox: https://pypi.org/project/tox
.. _trove classifier: https://pypi.org/classifiers
diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst
index d574c3736b1cb7..c4ebbd311e0fe3 100644
--- a/Doc/howto/regex.rst
+++ b/Doc/howto/regex.rst
@@ -89,7 +89,7 @@ is the same as ``[a-c]``, which uses a range to express the same set of
characters. If you wanted to match only lowercase letters, your RE would be
``[a-z]``.
-Metacharacters are not active inside classes. For example, ``[akm$]`` will
+Metacharacters (except ``\``) are not active inside classes. For example, ``[akm$]`` will
match any of the characters ``'a'``, ``'k'``, ``'m'``, or ``'$'``; ``'$'`` is
usually a metacharacter, but inside a character class it's stripped of its
special nature.
diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst
index d6ed128e073fd6..0bbf97da39768d 100644
--- a/Doc/howto/sockets.rst
+++ b/Doc/howto/sockets.rst
@@ -45,7 +45,7 @@ likely to be other forms of IPC that are faster, but for
cross-platform communication, sockets are about the only game in town.
They were invented in Berkeley as part of the BSD flavor of Unix. They spread
-like wildfire with the Internet. With good reason --- the combination of sockets
+like wildfire with the internet. With good reason --- the combination of sockets
with INET makes talking to arbitrary machines around the world unbelievably easy
(at least compared to other schemes).
@@ -252,20 +252,25 @@ Binary Data
-----------
It is perfectly possible to send binary data over a socket. The major problem is
-that not all machines use the same formats for binary data. For example, a
-Motorola chip will represent a 16 bit integer with the value 1 as the two hex
-bytes 00 01. Intel and DEC, however, are byte-reversed - that same 1 is 01 00.
+that not all machines use the same formats for binary data. For example,
+`network byte order `_
+is big-endian, with the most significant byte first,
+so a 16 bit integer with the value ``1`` would be the two hex bytes ``00 01``.
+However, most common processors (x86/AMD64, ARM, RISC-V), are little-endian,
+with the least significant byte first - that same ``1`` would be ``01 00``.
+
Socket libraries have calls for converting 16 and 32 bit integers - ``ntohl,
htonl, ntohs, htons`` where "n" means *network* and "h" means *host*, "s" means
*short* and "l" means *long*. Where network order is host order, these do
nothing, but where the machine is byte-reversed, these swap the bytes around
appropriately.
-In these days of 32 bit machines, the ascii representation of binary data is
+In these days of 64-bit machines, the ASCII representation of binary data is
frequently smaller than the binary representation. That's because a surprising
-amount of the time, all those longs have the value 0, or maybe 1. The string "0"
-would be two bytes, while binary is four. Of course, this doesn't fit well with
-fixed-length messages. Decisions, decisions.
+amount of the time, most integers have the value 0, or maybe 1.
+The string ``"0"`` would be two bytes, while a full 64-bit integer would be 8.
+Of course, this doesn't fit well with fixed-length messages.
+Decisions, decisions.
Disconnecting
diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst
index 37328c82dff270..32b47711f85705 100644
--- a/Doc/howto/sorting.rst
+++ b/Doc/howto/sorting.rst
@@ -325,7 +325,7 @@ Odd and Ends
>>> standard_way
[('red', 1), ('red', 2), ('blue', 1), ('blue', 2)]
-* The sort routines are guaranteed to use :meth:`__lt__` when making comparisons
+* The sort routines use ``<`` when making comparisons
between two objects. So, it is easy to add a standard sort order to a class by
defining an :meth:`__lt__` method:
@@ -335,6 +335,9 @@ Odd and Ends
>>> sorted(student_objects)
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+ However, note that ``<`` can fall back to using :meth:`__gt__` if
+ :meth:`__lt__` is not implemented (see :func:`object.__lt__`).
+
* Key functions need not depend directly on the objects being sorted. A key
function can also access external resources. For instance, if the student grades
are stored in a dictionary, they can be used to sort a separate list of student
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index 12d525771ddc28..e77fefffbd257d 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -4,13 +4,13 @@
HOWTO Fetch Internet Resources Using The urllib Package
***********************************************************
-:Author: `Michael Foord `_
+:Author: `Michael Foord `_
.. note::
There is a French translation of an earlier revision of this
HOWTO, available at `urllib2 - Le Manuel manquant
- `_.
+ `_.
@@ -22,7 +22,7 @@ Introduction
You may also find useful the following article on fetching web resources
with Python:
- * `Basic Authentication `_
+ * `Basic Authentication `_
A tutorial on *Basic Authentication*, with examples in Python.
diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c
index f361baf830dd1b..26ca754964733d 100644
--- a/Doc/includes/custom.c
+++ b/Doc/includes/custom.c
@@ -9,7 +9,7 @@ typedef struct {
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom.Custom",
- .tp_doc = "Custom objects",
+ .tp_doc = PyDoc_STR("Custom objects"),
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c
index 5bacab7a2a9714..2a3c59f8f04c3d 100644
--- a/Doc/includes/custom2.c
+++ b/Doc/includes/custom2.c
@@ -98,7 +98,7 @@ static PyMethodDef Custom_methods[] = {
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom2.Custom",
- .tp_doc = "Custom objects",
+ .tp_doc = PyDoc_STR("Custom objects"),
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c
index 2b7a99ecf96c76..5a47530f0a6b0d 100644
--- a/Doc/includes/custom3.c
+++ b/Doc/includes/custom3.c
@@ -148,7 +148,7 @@ static PyMethodDef Custom_methods[] = {
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom3.Custom",
- .tp_doc = "Custom objects",
+ .tp_doc = PyDoc_STR("Custom objects"),
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c
index 584992fc5f1a8a..c7ee55578488ed 100644
--- a/Doc/includes/custom4.c
+++ b/Doc/includes/custom4.c
@@ -160,7 +160,7 @@ static PyMethodDef Custom_methods[] = {
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom4.Custom",
- .tp_doc = "Custom objects",
+ .tp_doc = PyDoc_STR("Custom objects"),
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
diff --git a/Doc/includes/sqlite3/adapter_datetime.py b/Doc/includes/sqlite3/adapter_datetime.py
deleted file mode 100644
index d5221d80c35c8a..00000000000000
--- a/Doc/includes/sqlite3/adapter_datetime.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import sqlite3
-import datetime
-import time
-
-def adapt_datetime(ts):
- return time.mktime(ts.timetuple())
-
-sqlite3.register_adapter(datetime.datetime, adapt_datetime)
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-
-now = datetime.datetime.now()
-cur.execute("select ?", (now,))
-print(cur.fetchone()[0])
-
-con.close()
diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py
index 5df828e3361246..147807a2225ff0 100644
--- a/Doc/includes/sqlite3/converter_point.py
+++ b/Doc/includes/sqlite3/converter_point.py
@@ -5,28 +5,23 @@ def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
- return "(%f;%f)" % (self.x, self.y)
+ return f"Point({self.x}, {self.y})"
def adapt_point(point):
- return ("%f;%f" % (point.x, point.y)).encode('ascii')
+ return f"{point.x};{point.y}".encode("utf-8")
def convert_point(s):
x, y = list(map(float, s.split(b";")))
return Point(x, y)
-# Register the adapter
+# Register the adapter and converter
sqlite3.register_adapter(Point, adapt_point)
-
-# Register the converter
sqlite3.register_converter("point", convert_point)
+# 1) Parse using declared types
p = Point(4.0, -3.2)
-
-#########################
-# 1) Using declared types
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
-cur = con.cursor()
-cur.execute("create table test(p point)")
+cur = con.execute("create table test(p point)")
cur.execute("insert into test(p) values (?)", (p,))
cur.execute("select p from test")
@@ -34,11 +29,9 @@ def convert_point(s):
cur.close()
con.close()
-#######################
-# 1) Using column names
+# 2) Parse using column names
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
-cur = con.cursor()
-cur.execute("create table test(p)")
+cur = con.execute("create table test(p)")
cur.execute("insert into test(p) values (?)", (p,))
cur.execute('select p as "p [point]" from test')
diff --git a/Doc/includes/sqlite3/countcursors.py b/Doc/includes/sqlite3/countcursors.py
deleted file mode 100644
index 112f47703a2ff4..00000000000000
--- a/Doc/includes/sqlite3/countcursors.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import sqlite3
-
-class CountCursorsConnection(sqlite3.Connection):
- def __init__(self, *args, **kwargs):
- sqlite3.Connection.__init__(self, *args, **kwargs)
- self.numcursors = 0
-
- def cursor(self, *args, **kwargs):
- self.numcursors += 1
- return sqlite3.Connection.cursor(self, *args, **kwargs)
-
-con = sqlite3.connect(":memory:", factory=CountCursorsConnection)
-cur1 = con.cursor()
-cur2 = con.cursor()
-print(con.numcursors)
-
-con.close()
diff --git a/Doc/includes/sqlite3/createdb.py b/Doc/includes/sqlite3/createdb.py
deleted file mode 100644
index ee2950bdf81646..00000000000000
--- a/Doc/includes/sqlite3/createdb.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Not referenced from the documentation, but builds the database file the other
-# code snippets expect.
-
-import sqlite3
-import os
-
-DB_FILE = "mydb"
-
-if os.path.exists(DB_FILE):
- os.remove(DB_FILE)
-
-con = sqlite3.connect(DB_FILE)
-cur = con.cursor()
-cur.execute("""
- create table people
- (
- name_last varchar(20),
- age integer
- )
- """)
-
-cur.execute("insert into people (name_last, age) values ('Yeltsin', 72)")
-cur.execute("insert into people (name_last, age) values ('Putin', 51)")
-
-con.commit()
-
-cur.close()
-con.close()
diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py
index 6db77d45046e1f..2e1175ef44c641 100644
--- a/Doc/includes/sqlite3/ctx_manager.py
+++ b/Doc/includes/sqlite3/ctx_manager.py
@@ -1,19 +1,19 @@
import sqlite3
con = sqlite3.connect(":memory:")
-con.execute("create table person (id integer primary key, firstname varchar unique)")
+con.execute("create table lang (id integer primary key, name varchar unique)")
# Successful, con.commit() is called automatically afterwards
with con:
- con.execute("insert into person(firstname) values (?)", ("Joe",))
+ con.execute("insert into lang(name) values (?)", ("Python",))
# con.rollback() is called after the with block finishes with an exception, the
# exception is still raised and must be caught
try:
with con:
- con.execute("insert into person(firstname) values (?)", ("Joe",))
+ con.execute("insert into lang(name) values (?)", ("Python",))
except sqlite3.IntegrityError:
- print("couldn't add Joe twice")
+ print("couldn't add Python twice")
# Connection object used as context manager only commits or rollbacks transactions,
# so the connection object should be closed manually
diff --git a/Doc/includes/sqlite3/execsql_fetchonerow.py b/Doc/includes/sqlite3/execsql_fetchonerow.py
deleted file mode 100644
index 115bcb50c7c754..00000000000000
--- a/Doc/includes/sqlite3/execsql_fetchonerow.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect("mydb")
-
-cur = con.cursor()
-SELECT = "select name_last, age from people order by age, name_last"
-
-# 1. Iterate over the rows available from the cursor, unpacking the
-# resulting sequences to yield their elements (name_last, age):
-cur.execute(SELECT)
-for (name_last, age) in cur:
- print('%s is %d years old.' % (name_last, age))
-
-# 2. Equivalently:
-cur.execute(SELECT)
-for row in cur:
- print('%s is %d years old.' % (row[0], row[1]))
-
-con.close()
diff --git a/Doc/includes/sqlite3/execsql_printall_1.py b/Doc/includes/sqlite3/execsql_printall_1.py
deleted file mode 100644
index 19306e6e3ca7d1..00000000000000
--- a/Doc/includes/sqlite3/execsql_printall_1.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import sqlite3
-
-# Create a connection to the database file "mydb":
-con = sqlite3.connect("mydb")
-
-# Get a Cursor object that operates in the context of Connection con:
-cur = con.cursor()
-
-# Execute the SELECT statement:
-cur.execute("select * from people order by age")
-
-# Retrieve all rows as a sequence and print that sequence:
-print(cur.fetchall())
-
-con.close()
diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py
index 42aad4d5839f06..ee0000e2b94a32 100644
--- a/Doc/includes/sqlite3/execute_1.py
+++ b/Doc/includes/sqlite3/execute_1.py
@@ -2,22 +2,21 @@
con = sqlite3.connect(":memory:")
cur = con.cursor()
-cur.execute("create table lang (lang_name, lang_age)")
+cur.execute("create table lang (name, first_appeared)")
# This is the qmark style:
-cur.execute("insert into lang values (?, ?)", ("C", 49))
+cur.execute("insert into lang values (?, ?)", ("C", 1972))
# The qmark style used with executemany():
lang_list = [
- ("Fortran", 64),
- ("Python", 30),
- ("Go", 11),
+ ("Fortran", 1957),
+ ("Python", 1991),
+ ("Go", 2009),
]
cur.executemany("insert into lang values (?, ?)", lang_list)
# And this is the named style:
-cur.execute("select * from lang where lang_name=:name and lang_age=:age",
- {"name": "C", "age": 49})
+cur.execute("select * from lang where first_appeared=:year", {"year": 1972})
print(cur.fetchall())
con.close()
diff --git a/Doc/includes/sqlite3/insert_more_people.py b/Doc/includes/sqlite3/insert_more_people.py
deleted file mode 100644
index 10cf937243f6da..00000000000000
--- a/Doc/includes/sqlite3/insert_more_people.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect("mydb")
-
-cur = con.cursor()
-
-newPeople = (
- ('Lebed' , 53),
- ('Zhirinovsky' , 57),
- )
-
-for person in newPeople:
- cur.execute("insert into people (name_last, age) values (?, ?)", person)
-
-# The changes will not be saved unless the transaction is committed explicitly:
-con.commit()
-
-con.close()
diff --git a/Doc/includes/sqlite3/parse_colnames.py b/Doc/includes/sqlite3/parse_colnames.py
deleted file mode 100644
index 5f01dbfe1cb524..00000000000000
--- a/Doc/includes/sqlite3/parse_colnames.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import sqlite3
-import datetime
-
-con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
-cur = con.cursor()
-cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),))
-dt = cur.fetchone()[0]
-print(dt, type(dt))
-
-con.close()
diff --git a/Doc/includes/sqlite3/shared_cache.py b/Doc/includes/sqlite3/shared_cache.py
deleted file mode 100644
index 30e71c935ff62e..00000000000000
--- a/Doc/includes/sqlite3/shared_cache.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import sqlite3
-
-# The shared cache is only available in SQLite versions 3.3.3 or later
-# See the SQLite documentation for details.
-
-sqlite3.enable_shared_cache(True)
diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py
index 98a39411495cba..48ea6fad15a898 100644
--- a/Doc/includes/sqlite3/shortcut_methods.py
+++ b/Doc/includes/sqlite3/shortcut_methods.py
@@ -1,23 +1,23 @@
import sqlite3
-persons = [
- ("Hugo", "Boss"),
- ("Calvin", "Klein")
- ]
+langs = [
+ ("C++", 1985),
+ ("Objective-C", 1984),
+]
con = sqlite3.connect(":memory:")
# Create the table
-con.execute("create table person(firstname, lastname)")
+con.execute("create table lang(name, first_appeared)")
# Fill the table
-con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)
+con.executemany("insert into lang(name, first_appeared) values (?, ?)", langs)
# Print the table contents
-for row in con.execute("select firstname, lastname from person"):
+for row in con.execute("select name, first_appeared from lang"):
print(row)
-print("I just deleted", con.execute("delete from person").rowcount, "rows")
+print("I just deleted", con.execute("delete from lang").rowcount, "rows")
# close is not a shortcut method and it's not called automatically,
# so the connection object should be closed manually
diff --git a/Doc/includes/sqlite3/simple_tableprinter.py b/Doc/includes/sqlite3/simple_tableprinter.py
deleted file mode 100644
index 148a1707f948bc..00000000000000
--- a/Doc/includes/sqlite3/simple_tableprinter.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import sqlite3
-
-FIELD_MAX_WIDTH = 20
-TABLE_NAME = 'people'
-SELECT = 'select * from %s order by age, name_last' % TABLE_NAME
-
-con = sqlite3.connect("mydb")
-
-cur = con.cursor()
-cur.execute(SELECT)
-
-# Print a header.
-for fieldDesc in cur.description:
- print(fieldDesc[0].ljust(FIELD_MAX_WIDTH), end=' ')
-print() # Finish the header with a newline.
-print('-' * 78)
-
-# For each row, print the value of each field left-justified within
-# the maximum possible width of that field.
-fieldIndices = range(len(cur.description))
-for row in cur:
- for fieldIndex in fieldIndices:
- fieldValue = str(row[fieldIndex])
- print(fieldValue.ljust(FIELD_MAX_WIDTH), end=' ')
-
- print() # Finish the row with a newline.
-
-con.close()
diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py
index a857a155cdd4ff..c0d87cd559118c 100644
--- a/Doc/includes/sqlite3/text_factory.py
+++ b/Doc/includes/sqlite3/text_factory.py
@@ -3,9 +3,9 @@
con = sqlite3.connect(":memory:")
cur = con.cursor()
-AUSTRIA = "\xd6sterreich"
+AUSTRIA = "Österreich"
-# by default, rows are returned as Unicode
+# by default, rows are returned as str
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert row[0] == AUSTRIA
diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c
index b2c26e73ebaf7e..b36dadf07eae87 100644
--- a/Doc/includes/sublist.c
+++ b/Doc/includes/sublist.c
@@ -31,7 +31,7 @@ SubList_init(SubListObject *self, PyObject *args, PyObject *kwds)
static PyTypeObject SubListType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "sublist.SubList",
- .tp_doc = "SubList objects",
+ .tp_doc = PyDoc_STR("SubList objects"),
.tp_basicsize = sizeof(SubListObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
diff --git a/Doc/install/index.rst b/Doc/install/index.rst
index 48c6e76a682a46..7f7be117009887 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -206,7 +206,7 @@ directory.
If you don't choose an installation directory---i.e., if you just run ``setup.py
install``\ ---then the :command:`install` command installs to the standard
location for third-party Python modules. This location varies by platform and
-by how you built/installed Python itself. On Unix (and Mac OS X, which is also
+by how you built/installed Python itself. On Unix (and macOS, which is also
Unix-based), it also depends on whether the module distribution being installed
is pure Python or contains extensions ("non-pure"):
@@ -236,7 +236,7 @@ Notes:
:file:`{prefix}` and :file:`{exec-prefix}` stand for the directories that Python
is installed to, and where it finds its libraries at run-time. They are always
-the same under Windows, and very often the same under Unix and Mac OS X. You
+the same under Windows, and very often the same under Unix and macOS. You
can find out what your Python installation uses for :file:`{prefix}` and
:file:`{exec-prefix}` by running Python in interactive mode and typing a few
simple commands. Under Unix, just type ``python`` at the shell prompt. Under
@@ -312,7 +312,7 @@ install into it. It is enabled with a simple option::
Files will be installed into subdirectories of :data:`site.USER_BASE` (written
as :file:`{userbase}` hereafter). This scheme installs pure Python modules and
extension modules in the same location (also known as :data:`site.USER_SITE`).
-Here are the values for UNIX, including Mac OS X:
+Here are the values for UNIX, including macOS:
=============== ===========================================================
Type of file Installation directory
@@ -735,7 +735,7 @@ Location and names of config files
----------------------------------
The names and locations of the configuration files vary slightly across
-platforms. On Unix and Mac OS X, the three configuration files (in the order
+platforms. On Unix and macOS, the three configuration files (in the order
they are processed) are:
+--------------+----------------------------------------------------------+-------+
@@ -953,7 +953,7 @@ Borland/CodeGear C++
This subsection describes the necessary steps to use Distutils with the Borland
C++ compiler version 5.5. First you have to know that Borland's object file
format (OMF) is different from the format used by the Python version you can
-download from the Python or ActiveState Web site. (Python is built with
+download from the Python or ActiveState web site. (Python is built with
Microsoft Visual C++, which uses COFF as the object file format.) For this
reason you have to convert Python's library :file:`python25.lib` into the
Borland format. You can do this as follows:
diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst
index 31e9b0bde07244..e158bf1c4c0c7f 100644
--- a/Doc/installing/index.rst
+++ b/Doc/installing/index.rst
@@ -44,7 +44,7 @@ Key terms
``venv``. It allows virtual environments to be used on versions of
Python prior to 3.4, which either don't provide ``venv`` at all, or
aren't able to automatically install ``pip`` into created environments.
-* The `Python Packaging Index `__ is a public
+* The `Python Package Index `__ is a public
repository of open source licensed packages made available for use by
other Python users.
* the `Python Packaging Authority
@@ -78,13 +78,13 @@ The standard packaging tools are all designed to be used from the command
line.
The following command will install the latest version of a module and its
-dependencies from the Python Packaging Index::
+dependencies from the Python Package Index::
python -m pip install SomePackage
.. note::
- For POSIX users (including Mac OS X and Linux users), the examples in
+ For POSIX users (including macOS and Linux users), the examples in
this guide assume the use of a :term:`virtual environment`.
For Windows users, the examples in this guide assume that the option to
@@ -163,7 +163,7 @@ rather than attempting to install them with ``pip``.
... work with multiple versions of Python installed in parallel?
----------------------------------------------------------------
-On Linux, Mac OS X, and other POSIX systems, use the versioned Python commands
+On Linux, macOS, and other POSIX systems, use the versioned Python commands
in combination with the ``-m`` switch to run the appropriate copy of
``pip``::
@@ -214,7 +214,7 @@ It is possible that ``pip`` does not get installed by default. One potential fix
python -m ensurepip --default-pip
There are also additional resources for `installing pip.
-`__
+`__
Installing binary extensions
@@ -225,8 +225,8 @@ users being expected to compile extension modules from source as part of
the installation process.
With the introduction of support for the binary ``wheel`` format, and the
-ability to publish wheels for at least Windows and Mac OS X through the
-Python Packaging Index, this problem is expected to diminish over time,
+ability to publish wheels for at least Windows and macOS through the
+Python Package Index, this problem is expected to diminish over time,
as users are more regularly able to install pre-built extensions rather
than needing to build them themselves.
diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst
index 1d7bd262872905..5e1b010e9bb5f2 100644
--- a/Doc/library/2to3.rst
+++ b/Doc/library/2to3.rst
@@ -333,7 +333,8 @@ and off individually. They are described here in more detail.
.. 2to3fixer:: nonzero
- Renames :meth:`__nonzero__` to :meth:`~object.__bool__`.
+ Renames definitions of methods called :meth:`__nonzero__`
+ to :meth:`~object.__bool__`.
.. 2to3fixer:: numliterals
@@ -464,12 +465,15 @@ and off individually. They are described here in more detail.
--------------
-.. deprecated:: 3.10
- Python 3.9 will switch to a PEG parser (see :pep:`617`), and Python 3.10 may
- include new language syntax that is not parsable by lib2to3's LL(1) parser.
- The ``lib2to3`` module may be removed from the standard library in a future
- Python version. Consider third-party alternatives such as `LibCST`_ or
- `parso`_.
+.. deprecated-removed:: 3.11 3.13
+ Python 3.9 switched to a PEG parser (see :pep:`617`) while lib2to3 is
+ using a less flexible LL(1) parser. Python 3.10 includes new language
+ syntax that is not parsable by lib2to3's LL(1) parser (see :pep:`634`).
+ The ``lib2to3`` module was marked pending for deprecation in Python 3.9
+ (raising :exc:`PendingDeprecationWarning` on import) and fully deprecated
+ in Python 3.11 (raising :exc:`DeprecationWarning`).
+ It will be removed from the standard library in Python 3.13.
+ Consider third-party alternatives such as `LibCST`_ or `parso`_.
.. note::
diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst
index 24bbd90d02cf76..8bd23daee73977 100644
--- a/Doc/library/__future__.rst
+++ b/Doc/library/__future__.rst
@@ -90,12 +90,20 @@ language using this mechanism:
| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: |
| | | | *StopIteration handling inside generators* |
+------------------+-------------+--------------+---------------------------------------------+
-| annotations | 3.7.0b1 | 3.11 | :pep:`563`: |
+| annotations | 3.7.0b1 | TBD [1]_ | :pep:`563`: |
| | | | *Postponed evaluation of annotations* |
+------------------+-------------+--------------+---------------------------------------------+
.. XXX Adding a new entry? Remember to update simple_stmts.rst, too.
+.. [1]
+ ``from __future__ import annotations`` was previously scheduled to
+ become mandatory in Python 3.10, but the Python Steering Council
+ twice decided to delay the change
+ (`announcement for Python 3.10 `__;
+ `announcement for Python 3.11 `__).
+ No final decision has been made yet. See also :pep:`563` and :pep:`649`.
+
.. seealso::
diff --git a/Doc/library/__main__.rst b/Doc/library/__main__.rst
index a64faf1bbe3c84..d0a65e76b84237 100644
--- a/Doc/library/__main__.rst
+++ b/Doc/library/__main__.rst
@@ -1,25 +1,368 @@
-
-:mod:`__main__` --- Top-level script environment
-================================================
+:mod:`__main__` --- Top-level code environment
+==============================================
.. module:: __main__
- :synopsis: The environment where the top-level script is run.
+ :synopsis: The environment where top-level code is run. Covers command-line
+ interfaces, import-time behavior, and ``__name__ == '__main__'``.
--------------
-``'__main__'`` is the name of the scope in which top-level code executes.
-A module's __name__ is set equal to ``'__main__'`` when read from
-standard input, a script, or from an interactive prompt.
+In Python, the special name ``__main__`` is used for two important constructs:
+
+1. the name of the top-level environment of the program, which can be
+ checked using the ``__name__ == '__main__'`` expression; and
+2. the ``__main__.py`` file in Python packages.
+
+Both of these mechanisms are related to Python modules; how users interact with
+them and how they interact with each other. They are explained in detail
+below. If you're new to Python modules, see the tutorial section
+:ref:`tut-modules` for an introduction.
+
+
+.. _name_equals_main:
+
+``__name__ == '__main__'``
+---------------------------
+
+When a Python module or package is imported, ``__name__`` is set to the
+module's name. Usually, this is the name of the Python file itself without the
+``.py`` extension::
+
+ >>> import configparser
+ >>> configparser.__name__
+ 'configparser'
+
+If the file is part of a package, ``__name__`` will also include the parent
+package's path::
+
+ >>> from concurrent.futures import process
+ >>> process.__name__
+ 'concurrent.futures.process'
+
+However, if the module is executed in the top-level code environment,
+its ``__name__`` is set to the string ``'__main__'``.
+
+What is the "top-level code environment"?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``__main__`` is the name of the environment where top-level code is run.
+"Top-level code" is the first user-specified Python module that starts running.
+It's "top-level" because it imports all other modules that the program needs.
+Sometimes "top-level code" is called an *entry point* to the application.
+
+The top-level code environment can be:
+
+* the scope of an interactive prompt::
+
+ >>> __name__
+ '__main__'
+
+* the Python module passed to the Python interpreter as a file argument:
+
+ .. code-block:: shell-session
+
+ $ python3 helloworld.py
+ Hello, world!
+
+* the Python module or package passed to the Python interpreter with the
+ :option:`-m` argument:
+
+ .. code-block:: shell-session
+
+ $ python3 -m tarfile
+ usage: tarfile.py [-h] [-v] (...)
+
+* Python code read by the Python interpreter from standard input:
+
+ .. code-block:: shell-session
+
+ $ echo "import this" | python3
+ The Zen of Python, by Tim Peters
+
+ Beautiful is better than ugly.
+ Explicit is better than implicit.
+ ...
+
+* Python code passed to the Python interpreter with the :option:`-c` argument:
+
+ .. code-block:: shell-session
+
+ $ python3 -c "import this"
+ The Zen of Python, by Tim Peters
+
+ Beautiful is better than ugly.
+ Explicit is better than implicit.
+ ...
+
+In each of these situations, the top-level module's ``__name__`` is set to
+``'__main__'``.
+
+As a result, a module can discover whether or not it is running in the
+top-level environment by checking its own ``__name__``, which allows a common
+idiom for conditionally executing code when the module is not initialized from
+an import statement::
+
+ if __name__ == '__main__':
+ # Execute when the module is not initialized from an import statement.
+ ...
+
+.. seealso::
+
+ For a more detailed look at how ``__name__`` is set in all situations, see
+ the tutorial section :ref:`tut-modules`.
+
+
+Idiomatic Usage
+^^^^^^^^^^^^^^^
+
+Some modules contain code that is intended for script use only, like parsing
+command-line arguments or fetching data from standard input. If a module
+like this was imported from a different module, for example to unit test
+it, the script code would unintentionally execute as well.
+
+This is where using the ``if __name__ == '__main__'`` code block comes in
+handy. Code within this block won't run unless the module is executed in the
+top-level environment.
+
+Putting as few statements as possible in the block below ``if __name___ ==
+'__main__'`` can improve code clarity and correctness. Most often, a function
+named ``main`` encapsulates the program's primary behavior::
+
+ # echo.py
+
+ import shlex
+ import sys
+
+ def echo(phrase: str) -> None:
+ """A dummy wrapper around print."""
+ # for demonstration purposes, you can imagine that there is some
+ # valuable and reusable logic inside this function
+ print(phrase)
+
+ def main() -> int:
+ """Echo the input arguments to standard output"""
+ phrase = shlex.join(sys.argv)
+ echo(phrase)
+ return 0
+
+ if __name__ == '__main__':
+ sys.exit(main()) # next section explains the use of sys.exit
+
+Note that if the module didn't encapsulate code inside the ``main`` function
+but instead put it directly within the ``if __name__ == '__main__'`` block,
+the ``phrase`` variable would be global to the entire module. This is
+error-prone as other functions within the module could be unintentionally using
+the global variable instead of a local name. A ``main`` function solves this
+problem.
+
+Using a ``main`` function has the added benefit of the ``echo`` function itself
+being isolated and importable elsewhere. When ``echo.py`` is imported, the
+``echo`` and ``main`` functions will be defined, but neither of them will be
+called, because ``__name__ != '__main__'``.
+
+
+Packaging Considerations
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+``main`` functions are often used to create command-line tools by specifying
+them as entry points for console scripts. When this is done,
+`pip `_ inserts the function call into a template script,
+where the return value of ``main`` is passed into :func:`sys.exit`.
+For example::
+
+ sys.exit(main())
+
+Since the call to ``main`` is wrapped in :func:`sys.exit`, the expectation is
+that your function will return some value acceptable as an input to
+:func:`sys.exit`; typically, an integer or ``None`` (which is implicitly
+returned if your function does not have a return statement).
+
+By proactively following this convention ourselves, our module will have the
+same behavior when run directly (i.e. ``python3 echo.py``) as it will have if
+we later package it as a console script entry-point in a pip-installable
+package.
+
+In particular, be careful about returning strings from your ``main`` function.
+:func:`sys.exit` will interpret a string argument as a failure message, so
+your program will have an exit code of ``1``, indicating failure, and the
+string will be written to :data:`sys.stderr`. The ``echo.py`` example from
+earlier exemplifies using the ``sys.exit(main())`` convention.
+
+.. seealso::
+
+ `Python Packaging User Guide `_
+ contains a collection of tutorials and references on how to distribute and
+ install Python packages with modern tools.
+
+
+``__main__.py`` in Python Packages
+----------------------------------
+
+If you are not familiar with Python packages, see section :ref:`tut-packages`
+of the tutorial. Most commonly, the ``__main__.py`` file is used to provide
+a command-line interface for a package. Consider the following hypothetical
+package, "bandclass":
+
+.. code-block:: text
+
+ bandclass
+ ├── __init__.py
+ ├── __main__.py
+ └── student.py
+
+``__main__.py`` will be executed when the package itself is invoked
+directly from the command line using the :option:`-m` flag. For example:
+
+.. code-block:: shell-session
+
+ $ python3 -m bandclass
+
+This command will cause ``__main__.py`` to run. How you utilize this mechanism
+will depend on the nature of the package you are writing, but in this
+hypothetical case, it might make sense to allow the teacher to search for
+students::
+
+ # bandclass/__main__.py
+
+ import sys
+ from .student import search_students
+
+ student_name = sys.argv[2] if len(sys.argv) >= 2 else ''
+ print(f'Found student: {search_students(student_name)}')
+
+Note that ``from .student import search_students`` is an example of a relative
+import. This import style can be used when referencing modules within a
+package. For more details, see :ref:`intra-package-references` in the
+:ref:`tut-modules` section of the tutorial.
+
+Idiomatic Usage
+^^^^^^^^^^^^^^^
+
+The contents of ``__main__.py`` typically isn't fenced with
+``if __name__ == '__main__'`` blocks. Instead, those files are kept short,
+functions to execute from other modules. Those other modules can then be
+easily unit-tested and are properly reusable.
+
+If used, an ``if __name__ == '__main__'`` block will still work as expected
+for a ``__main__.py`` file within a package, because its ``__name__``
+attribute will include the package's path if imported::
+
+ >>> import asyncio.__main__
+ >>> asyncio.__main__.__name__
+ 'asyncio.__main__'
+
+This won't work for ``__main__.py`` files in the root directory of a .zip file
+though. Hence, for consistency, minimal ``__main__.py`` like the :mod:`venv`
+one mentioned below are preferred.
+
+.. seealso::
+
+ See :mod:`venv` for an example of a package with a minimal ``__main__.py``
+ in the standard library. It doesn't contain a ``if __name__ == '__main__'``
+ block. You can invoke it with ``python3 -m venv [directory]``.
+
+ See :mod:`runpy` for more details on the :option:`-m` flag to the
+ interpreter executable.
+
+ See :mod:`zipapp` for how to run applications packaged as *.zip* files. In
+ this case Python looks for a ``__main__.py`` file in the root directory of
+ the archive.
+
+
+
+``import __main__``
+-------------------
+
+Regardless of which module a Python program was started with, other modules
+running within that same program can import the top-level environment's scope
+(:term:`namespace`) by importing the ``__main__`` module. This doesn't import
+a ``__main__.py`` file but rather whichever module that received the special
+name ``'__main__'``.
+
+Here is an example module that consumes the ``__main__`` namespace::
+
+ # namely.py
+
+ import __main__
+
+ def did_user_define_their_name():
+ return 'my_name' in dir(__main__)
+
+ def print_user_name():
+ if not did_user_define_their_name():
+ raise ValueError('Define the variable `my_name`!')
+
+ if '__file__' in dir(__main__):
+ print(__main__.my_name, "found in file", __main__.__file__)
+ else:
+ print(__main__.my_name)
+
+Example usage of this module could be as follows::
+
+ # start.py
+
+ import sys
+
+ from namely import print_user_name
+
+ # my_name = "Dinsdale"
+
+ def main():
+ try:
+ print_user_name()
+ except ValueError as ve:
+ return str(ve)
+
+ if __name__ == "__main__":
+ sys.exit(main())
+
+Now, if we started our program, the result would look like this:
+
+.. code-block:: shell-session
+
+ $ python3 start.py
+ Define the variable `my_name`!
+
+The exit code of the program would be 1, indicating an error. Uncommenting the
+line with ``my_name = "Dinsdale"`` fixes the program and now it exits with
+status code 0, indicating success:
+
+.. code-block:: shell-session
+
+ $ python3 start.py
+ Dinsdale found in file /path/to/start.py
+
+Note that importing ``__main__`` doesn't cause any issues with unintentionally
+running top-level code meant for script use which is put in the
+``if __name__ == "__main__"`` block of the ``start`` module. Why does this work?
+
+Python inserts an empty ``__main__`` module in :attr:`sys.modules` at
+interpreter startup, and populates it by running top-level code. In our example
+this is the ``start`` module which runs line by line and imports ``namely``.
+In turn, ``namely`` imports ``__main__`` (which is really ``start``). That's an
+import cycle! Fortunately, since the partially populated ``__main__``
+module is present in :attr:`sys.modules`, Python passes that to ``namely``.
+See :ref:`Special considerations for __main__ ` in the
+import system's reference for details on how this works.
+
+The Python REPL is another example of a "top-level environment", so anything
+defined in the REPL becomes part of the ``__main__`` scope::
-A module can discover whether or not it is running in the main scope by
-checking its own ``__name__``, which allows a common idiom for conditionally
-executing code in a module when it is run as a script or with ``python
--m`` but not when it is imported::
+ >>> import namely
+ >>> namely.did_user_define_their_name()
+ False
+ >>> namely.print_user_name()
+ Traceback (most recent call last):
+ ...
+ ValueError: Define the variable `my_name`!
+ >>> my_name = 'Jabberwocky'
+ >>> namely.did_user_define_their_name()
+ True
+ >>> namely.print_user_name()
+ Jabberwocky
- if __name__ == "__main__":
- # execute only if run as a script
- main()
+Note that in this case the ``__main__`` scope doesn't contain a ``__file__``
+attribute as it's interactive.
-For a package, the same effect can be achieved by including a
-``__main__.py`` module, the contents of which will be executed when the
-module is run with ``-m``.
+The ``__main__`` scope is used in the implementation of :mod:`pdb` and
+:mod:`rlcompleter`.
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index 1a6ed474ff21da..3b74622e7ff46c 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -186,15 +186,15 @@ The :mod:`abc` module also provides the following decorator:
class C(ABC):
@abstractmethod
- def my_abstract_method(self, ...):
+ def my_abstract_method(self, arg1):
...
@classmethod
@abstractmethod
- def my_abstract_classmethod(cls, ...):
+ def my_abstract_classmethod(cls, arg2):
...
@staticmethod
@abstractmethod
- def my_abstract_staticmethod(...):
+ def my_abstract_staticmethod(arg3):
...
@property
@@ -255,7 +255,7 @@ The :mod:`abc` module also supports the following legacy decorators:
class C(ABC):
@classmethod
@abstractmethod
- def my_abstract_classmethod(cls, ...):
+ def my_abstract_classmethod(cls, arg):
...
@@ -276,7 +276,7 @@ The :mod:`abc` module also supports the following legacy decorators:
class C(ABC):
@staticmethod
@abstractmethod
- def my_abstract_staticmethod(...):
+ def my_abstract_staticmethod(arg):
...
diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst
index 2e917cf7321b85..fa277857574a3a 100644
--- a/Doc/library/aifc.rst
+++ b/Doc/library/aifc.rst
@@ -3,6 +3,7 @@
.. module:: aifc
:synopsis: Read and write audio files in AIFF or AIFC format.
+ :deprecated:
**Source code:** :source:`Lib/aifc.py`
@@ -11,6 +12,11 @@
single: AIFF
single: AIFF-C
+
+.. deprecated:: 3.11
+ The :mod:`aifc` module is deprecated
+ (see :pep:`PEP 594 <594#aifc>` for details).
+
--------------
This module provides support for reading and writing AIFF and AIFF-C files.
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index b2eb9eff914c69..d96f17b80a5f0f 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -148,7 +148,8 @@ ArgumentParser objects
as keyword arguments. Each parameter has its own more detailed description
below, but in short they are:
- * prog_ - The name of the program (default: ``sys.argv[0]``)
+ * prog_ - The name of the program (default:
+ ``os.path.basename(sys.argv[0])``)
* usage_ - The string describing the program usage (default: generated from
arguments added to parser)
@@ -501,7 +502,7 @@ disallowed.
fromfile_prefix_chars
^^^^^^^^^^^^^^^^^^^^^
-Sometimes, for example when dealing with a particularly long argument lists, it
+Sometimes, for example when dealing with a particularly long argument list, it
may make sense to keep the list of arguments in a file rather than typing it out
at the command line. If the ``fromfile_prefix_chars=`` argument is given to the
:class:`ArgumentParser` constructor, then arguments that start with any of the
@@ -853,6 +854,8 @@ is available in ``argparse`` and adds support for boolean actions such as
>>> parser.parse_args(['--no-foo'])
Namespace(foo=False)
+.. versionadded:: 3.9
+
The recommended way to create a custom action is to extend :class:`Action`,
overriding the ``__call__`` method and optionally the ``__init__`` and
``format_usage`` methods.
@@ -1102,7 +1105,7 @@ Anything with more interesting error-handling or resource management should be
done downstream after the arguments are parsed.
For example, JSON or YAML conversions have complex error cases that require
-better reporting than can be given by the ``type`` keyword. An
+better reporting than can be given by the ``type`` keyword. A
:exc:`~json.JSONDecodeError` would not be well formatted and a
:exc:`FileNotFound` exception would not be handled at all.
@@ -1612,7 +1615,7 @@ Sub-commands
.. method:: ArgumentParser.add_subparsers([title], [description], [prog], \
[parser_class], [action], \
- [option_string], [dest], [required], \
+ [option_strings], [dest], [required], \
[help], [metavar])
Many programs split up their functionality into a number of sub-commands,
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index c7f137d15b4b86..975670cc81a202 100644
--- a/Doc/library/array.rst
+++ b/Doc/library/array.rst
@@ -52,7 +52,7 @@ Notes:
.. versionchanged:: 3.9
``array('u')`` now uses ``wchar_t`` as C type instead of deprecated
- ``Py_UNICODE``. This change doesn't affect to its behavior because
+ ``Py_UNICODE``. This change doesn't affect its behavior because
``Py_UNICODE`` is alias of ``wchar_t`` since Python 3.3.
.. deprecated-removed:: 3.3 4.0
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index c7074c40f280c6..e29b5e88d71d41 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -1266,7 +1266,7 @@ Pattern matching
the pattern matches the subject.
``body`` contains a list of nodes to execute if the pattern matches and
- the result of evaluating the guard expression is truthy.
+ the result of evaluating the guard expression is true.
.. doctest::
@@ -1621,7 +1621,7 @@ Function and class definitions
A function definition.
* ``name`` is a raw string of the function name.
- * ``args`` is a :class:`arguments` node.
+ * ``args`` is an :class:`arguments` node.
* ``body`` is the list of nodes inside the function.
* ``decorator_list`` is the list of decorators to be applied, stored outermost
first (i.e. the first in the list will be applied last).
@@ -1795,7 +1795,7 @@ Function and class definitions
* ``bases`` is a list of nodes for explicitly specified base classes.
* ``keywords`` is a list of :class:`keyword` nodes, principally for 'metaclass'.
Other keywords will be passed to the metaclass, as per `PEP-3115
- `_.
+ `_.
* ``starargs`` and ``kwargs`` are each a single node, as in a function call.
starargs will be expanded to join the list of base classes, and kwargs will
be passed to the metaclass.
@@ -1917,6 +1917,19 @@ and classes for traversing abstract syntax trees:
``await`` as variable names. The lowest supported version is
``(3, 4)``; the highest is ``sys.version_info[0:2]``.
+ If source contains a null character ('\0'), :exc:`ValueError` is raised.
+
+ .. warning::
+ Note that successfully parsing source code into an AST object doesn't
+ guarantee that the source code provided is valid Python code that can
+ be executed as the compilation step can raise further :exc:`SyntaxError`
+ exceptions. For instance, the source ``return 42`` generates a valid
+ AST node for a return statement, but it cannot be compiled alone (it needs
+ to be inside a function node).
+
+ In particular, :func:`ast.parse` won't do any scoping checks, which the
+ compilation step does.
+
.. warning::
It is possible to crash the Python interpreter with a
sufficiently large/complex string due to stack depth limitations
diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst
index 9e51416b83a570..7cc9d99779bbbb 100644
--- a/Doc/library/asynchat.rst
+++ b/Doc/library/asynchat.rst
@@ -3,6 +3,7 @@
.. module:: asynchat
:synopsis: Support for asynchronous command/response protocols.
+ :deprecated:
.. moduleauthor:: Sam Rushing
.. sectionauthor:: Steve Holden
@@ -10,6 +11,8 @@
**Source code:** :source:`Lib/asynchat.py`
.. deprecated:: 3.6
+ :mod:`asynchat` will be removed in Python 3.12
+ (see :pep:`PEP 594 <594#asynchat>` for details).
Please use :mod:`asyncio` instead.
--------------
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index ca91efec260db2..300092d71b1cb1 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -55,7 +55,7 @@ an event loop:
.. deprecated:: 3.10
Deprecation warning is emitted if there is no running event loop.
- If future Python releases this function will be an alias of
+ In future Python releases, this function will be an alias of
:func:`get_running_loop`.
.. function:: set_event_loop(loop)
@@ -64,7 +64,7 @@ an event loop:
.. function:: new_event_loop()
- Create a new event loop object.
+ Create and return a new event loop object.
Note that the behaviour of :func:`get_event_loop`, :func:`set_event_loop`,
and :func:`new_event_loop` functions can be altered by
@@ -216,6 +216,10 @@ Scheduling callbacks
A thread-safe variant of :meth:`call_soon`. Must be used to
schedule callbacks *from another thread*.
+ Raises :exc:`RuntimeError` if called on a loop that's been closed.
+ This can happen on a secondary thread when the main application is
+ shutting down.
+
See the :ref:`concurrency and multithreading `
section of the documentation.
@@ -339,7 +343,7 @@ Creating Futures and Tasks
the name of the task using :meth:`Task.set_name`.
.. versionchanged:: 3.8
- Added the ``name`` parameter.
+ Added the *name* parameter.
.. method:: loop.set_task_factory(factory)
@@ -445,14 +449,27 @@ Opening network connections
and *local_addr* should be specified.
* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
- to bind the socket to locally. The *local_host* and *local_port*
+ to bind the socket locally. The *local_host* and *local_port*
are looked up using ``getaddrinfo()``, similarly to *host* and *port*.
* *ssl_handshake_timeout* is (for a TLS connection) the time in seconds
to wait for the TLS handshake to complete before aborting the connection.
``60.0`` seconds if ``None`` (default).
- .. versionadded:: 3.8
+ .. versionchanged:: 3.5
+
+ Added support for SSL/TLS in :class:`ProactorEventLoop`.
+
+ .. versionchanged:: 3.6
+
+ The socket option :py:data:`~socket.TCP_NODELAY` is set by default
+ for all TCP connections.
+
+ .. versionchanged:: 3.7
+
+ Added the *ssl_handshake_timeout* parameter.
+
+ .. versionchanged:: 3.8
Added the *happy_eyeballs_delay* and *interleave* parameters.
@@ -467,19 +484,6 @@ Opening network connections
For more information: https://tools.ietf.org/html/rfc6555
- .. versionadded:: 3.7
-
- The *ssl_handshake_timeout* parameter.
-
- .. versionchanged:: 3.6
-
- The socket option :py:data:`~socket.TCP_NODELAY` is set by default
- for all TCP connections.
-
- .. versionchanged:: 3.5
-
- Added support for SSL/TLS in :class:`ProactorEventLoop`.
-
.. seealso::
The :func:`open_connection` function is a high-level alternative
@@ -523,7 +527,7 @@ Opening network connections
Other arguments:
* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
- to bind the socket to locally. The *local_host* and *local_port*
+ to bind the socket locally. The *local_host* and *local_port*
are looked up using :meth:`getaddrinfo`.
* *remote_addr*, if given, is a ``(remote_host, remote_port)`` tuple used
@@ -584,12 +588,8 @@ Opening network connections
.. availability:: Unix.
- .. versionadded:: 3.7
-
- The *ssl_handshake_timeout* parameter.
-
.. versionchanged:: 3.7
-
+ Added the *ssl_handshake_timeout* parameter.
The *path* parameter can now be a :term:`path-like object`.
@@ -627,6 +627,11 @@ Creating network servers
assumed and a list of multiple sockets will be returned (most likely
one for IPv4 and another one for IPv6).
+ * The *port* parameter can be set to specify which port the server should
+ listen on. If ``0`` or ``None`` (the default), a random unused port will
+ be selected (note that if *host* resolves to multiple network interfaces,
+ a different random port will be selected for each interface).
+
* *family* can be set to either :data:`socket.AF_INET` or
:data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6.
If not set, the *family* will be determined from host name
@@ -663,15 +668,6 @@ Creating network servers
:meth:`Server.serve_forever` to make the server to start accepting
connections.
- .. versionadded:: 3.7
-
- Added *ssl_handshake_timeout* and *start_serving* parameters.
-
- .. versionchanged:: 3.6
-
- The socket option :py:data:`~socket.TCP_NODELAY` is set by default
- for all TCP connections.
-
.. versionchanged:: 3.5
Added support for SSL/TLS in :class:`ProactorEventLoop`.
@@ -680,6 +676,12 @@ Creating network servers
The *host* parameter can be a sequence of strings.
+ .. versionchanged:: 3.6
+
+ Added *ssl_handshake_timeout* and *start_serving* parameters.
+ The socket option :py:data:`~socket.TCP_NODELAY` is set by default
+ for all TCP connections.
+
.. seealso::
The :func:`start_server` function is a higher-level alternative API
@@ -704,12 +706,9 @@ Creating network servers
.. availability:: Unix.
- .. versionadded:: 3.7
-
- The *ssl_handshake_timeout* and *start_serving* parameters.
-
.. versionchanged:: 3.7
+ Added the *ssl_handshake_timeout* and *start_serving* parameters.
The *path* parameter can now be a :class:`~pathlib.Path` object.
.. coroutinemethod:: loop.connect_accepted_socket(protocol_factory, \
@@ -737,11 +736,11 @@ Creating network servers
Returns a ``(transport, protocol)`` pair.
- .. versionadded:: 3.7
+ .. versionadded:: 3.5.3
- The *ssl_handshake_timeout* parameter.
+ .. versionchanged:: 3.7
- .. versionadded:: 3.5.3
+ Added the *ssl_handshake_timeout* parameter.
Transferring files
@@ -1238,9 +1237,10 @@ async/await code consider using the high-level
.. note::
- The default asyncio event loop on **Windows** does not support
- subprocesses. See :ref:`Subprocess Support on Windows
- ` for details.
+ On Windows, the default event loop :class:`ProactorEventLoop` supports
+ subprocesses, whereas :class:`SelectorEventLoop` does not. See
+ :ref:`Subprocess Support on Windows ` for
+ details.
.. coroutinemethod:: loop.subprocess_exec(protocol_factory, *args, \
stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst
index ef496a23f5cd4c..7426e8291e1424 100644
--- a/Doc/library/asyncio-future.rst
+++ b/Doc/library/asyncio-future.rst
@@ -54,6 +54,9 @@ Future Functions
See also the :func:`create_task` function which is the
preferred way for creating new Tasks.
+ Save a reference to the result of this function, to avoid
+ a task disappearing mid execution.
+
.. versionchanged:: 3.5.1
The function accepts any :term:`awaitable` object.
@@ -191,7 +194,7 @@ Future Object
schedule the callbacks, and return ``True``.
.. versionchanged:: 3.9
- Added the ``msg`` parameter.
+ Added the *msg* parameter.
.. method:: exception()
diff --git a/Doc/library/asyncio-llapi-index.rst b/Doc/library/asyncio-llapi-index.rst
index 0ab322af6dc72d..0315d2e3d37d95 100644
--- a/Doc/library/asyncio-llapi-index.rst
+++ b/Doc/library/asyncio-llapi-index.rst
@@ -349,6 +349,10 @@ pipes, etc). Returned from methods like
* - :meth:`transport.get_write_buffer_size()
`
+ - Return the current size of the output buffer.
+
+ * - :meth:`transport.get_write_buffer_limits()
+ `
- Return high and low water marks for write flow control.
* - :meth:`transport.set_write_buffer_limits()
diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst
index 9dbd3ab46a3f68..8b67f4b8957ef6 100644
--- a/Doc/library/asyncio-protocol.rst
+++ b/Doc/library/asyncio-protocol.rst
@@ -683,7 +683,7 @@ factories passed to the :meth:`loop.create_datagram_endpoint` method.
Subprocess Protocols
--------------------
-Datagram Protocol instances should be constructed by protocol
+Subprocess Protocol instances should be constructed by protocol
factories passed to the :meth:`loop.subprocess_exec` and
:meth:`loop.subprocess_shell` methods.
diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst
index 289ad1b014c356..d86fbc21351e2d 100644
--- a/Doc/library/asyncio-queue.rst
+++ b/Doc/library/asyncio-queue.rst
@@ -36,6 +36,9 @@ Queue
the queue is always known and can be returned by calling the
:meth:`qsize` method.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
This class is :ref:`not thread safe `.
diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst
index ad3c7442ad56cd..65f3d5322db2e6 100644
--- a/Doc/library/asyncio-stream.rst
+++ b/Doc/library/asyncio-stream.rst
@@ -51,7 +51,8 @@ and work with streams:
.. coroutinefunction:: open_connection(host=None, port=None, *, \
limit=None, ssl=None, family=0, proto=0, \
flags=0, sock=None, local_addr=None, \
- server_hostname=None, ssl_handshake_timeout=None)
+ server_hostname=None, ssl_handshake_timeout=None, \
+ happy_eyeballs_delay=None, interleave=None)
Establish a network connection and return a pair of
``(reader, writer)`` objects.
@@ -66,9 +67,15 @@ and work with streams:
The rest of the arguments are passed directly to
:meth:`loop.create_connection`.
- .. versionadded:: 3.7
+ .. versionchanged:: 3.7
+ Added the *ssl_handshake_timeout* parameter.
+
+ .. versionadded:: 3.8
+ Added *happy_eyeballs_delay* and *interleave* parameters.
+
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
- The *ssl_handshake_timeout* parameter.
.. coroutinefunction:: start_server(client_connected_cb, host=None, \
port=None, *, limit=None, \
@@ -96,9 +103,11 @@ and work with streams:
The rest of the arguments are passed directly to
:meth:`loop.create_server`.
- .. versionadded:: 3.7
+ .. versionchanged:: 3.7
+ Added the *ssl_handshake_timeout* and *start_serving* parameters.
- The *ssl_handshake_timeout* and *start_serving* parameters.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
.. rubric:: Unix Sockets
@@ -116,14 +125,13 @@ and work with streams:
.. availability:: Unix.
- .. versionadded:: 3.7
-
- The *ssl_handshake_timeout* parameter.
-
.. versionchanged:: 3.7
-
+ Added the *ssl_handshake_timeout* parameter.
The *path* parameter can now be a :term:`path-like object`
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \
*, limit=None, sock=None, backlog=100, ssl=None, \
@@ -137,14 +145,13 @@ and work with streams:
.. availability:: Unix.
- .. versionadded:: 3.7
-
- The *ssl_handshake_timeout* and *start_serving* parameters.
-
.. versionchanged:: 3.7
-
+ Added the *ssl_handshake_timeout* and *start_serving* parameters.
The *path* parameter can now be a :term:`path-like object`.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
StreamReader
============
@@ -185,7 +192,7 @@ StreamReader
can be read. Use the :attr:`IncompleteReadError.partial`
attribute to get the partially read data.
- .. coroutinemethod:: readuntil(separator=b'\\n')
+ .. coroutinemethod:: readuntil(separator=b'\n')
Read data from the stream until *separator* is found.
@@ -366,8 +373,8 @@ TCP echo server using the :func:`asyncio.start_server` function::
server = await asyncio.start_server(
handle_echo, '127.0.0.1', 8888)
- addr = server.sockets[0].getsockname()
- print(f'Serving on {addr}')
+ addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
+ print(f'Serving on {addrs}')
async with server:
await server.serve_forever()
diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst
index ef4d9bcc434c9f..28d0b21e8180b6 100644
--- a/Doc/library/asyncio-subprocess.rst
+++ b/Doc/library/asyncio-subprocess.rst
@@ -75,6 +75,9 @@ Creating Subprocesses
See the documentation of :meth:`loop.subprocess_exec` for other
parameters.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, \
stdout=None, stderr=None, limit=None, **kwds)
@@ -99,6 +102,9 @@ Creating Subprocesses
escape whitespace and special shell characters in strings that are going
to be used to construct shell commands.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. note::
Subprocesses are available for Windows if a :class:`ProactorEventLoop` is
@@ -118,6 +124,7 @@ Constants
=========
.. data:: asyncio.subprocess.PIPE
+ :module:
Can be passed to the *stdin*, *stdout* or *stderr* parameters.
@@ -131,11 +138,13 @@ Constants
attributes will point to :class:`StreamReader` instances.
.. data:: asyncio.subprocess.STDOUT
+ :module:
Special value that can be used as the *stderr* argument and indicates
that standard error should be redirected into standard output.
.. data:: asyncio.subprocess.DEVNULL
+ :module:
Special value that can be used as the *stdin*, *stdout* or *stderr* argument
to process creation functions. It indicates that the special file
@@ -151,6 +160,7 @@ wrapper that allows communicating with subprocesses and watching for
their completion.
.. class:: asyncio.subprocess.Process
+ :module:
An object that wraps OS processes created by the
:func:`create_subprocess_exec` and :func:`create_subprocess_shell`
@@ -269,7 +279,7 @@ their completion.
Use the :meth:`communicate` method rather than
:attr:`process.stdin.write() `,
:attr:`await process.stdout.read() ` or
- :attr:`await process.stderr.read `.
+ :attr:`await process.stderr.read() `.
This avoids deadlocks due to streams pausing reading or writing
and blocking the child process.
diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst
index d12630afc6a326..f4063db2ee86e6 100644
--- a/Doc/library/asyncio-sync.rst
+++ b/Doc/library/asyncio-sync.rst
@@ -63,6 +63,9 @@ Lock
finally:
lock.release()
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. coroutinemethod:: acquire()
Acquire the lock.
@@ -105,6 +108,9 @@ Event
:meth:`clear` method. The :meth:`~Event.wait` method blocks until the
flag is set to *true*. The flag is set to *false* initially.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. _asyncio_example_sync_event:
Example::
@@ -177,6 +183,9 @@ Condition
``None``. In the latter case a new Lock object is created
automatically.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
The preferred way to use a Condition is an :keyword:`async with`
statement::
@@ -273,6 +282,9 @@ Semaphore
internal counter (``1`` by default). If the given value is
less than ``0`` a :exc:`ValueError` is raised.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
The preferred way to use a Semaphore is an :keyword:`async with`
statement::
@@ -325,6 +337,9 @@ BoundedSemaphore
a :exc:`ValueError` in :meth:`~Semaphore.release` if it
increases the internal counter above the initial *value*.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
---------
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index 3f54ecb08efc1f..e535a5bf042542 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -20,7 +20,7 @@ Coroutines
:term:`Coroutines ` declared with the async/await syntax is the
preferred way of writing asyncio applications. For example, the following
-snippet of code (requires Python 3.7+) prints "hello", waits 1 second,
+snippet of code prints "hello", waits 1 second,
and then prints "world"::
>>> import asyncio
@@ -259,25 +259,32 @@ Creating Tasks
:exc:`RuntimeError` is raised if there is no running loop in
current thread.
- This function has been **added in Python 3.7**. Prior to
- Python 3.7, the low-level :func:`asyncio.ensure_future` function
- can be used instead::
+ .. important::
- async def coro():
- ...
+ Save a reference to the result of this function, to avoid
+ a task disappearing mid execution. The event loop only keeps
+ weak references to tasks. A task that isn't referenced elsewhere
+ may get garbage-collected at any time, even before it's done.
+ For reliable "fire-and-forget" background tasks, gather them in
+ a collection::
- # In Python 3.7+
- task = asyncio.create_task(coro())
- ...
+ background_tasks = set()
- # This works in all Python versions but is less readable
- task = asyncio.ensure_future(coro())
- ...
+ for i in range(10):
+ task = asyncio.create_task(some_coro(param=i))
+
+ # Add task to the set. This creates a strong reference.
+ background_tasks.add(task)
+
+ # To prevent keeping references to finished tasks forever,
+ # make each task remove its own reference from the set after
+ # completion:
+ task.add_done_callback(background_tasks.discard)
.. versionadded:: 3.7
.. versionchanged:: 3.8
- Added the ``name`` parameter.
+ Added the *name* parameter.
Sleeping
@@ -297,6 +304,12 @@ Sleeping
tasks to run. This can be used by long-running functions to avoid
blocking the event loop for the full duration of the function call.
+ .. deprecated-removed:: 3.8 3.10
+ The ``loop`` parameter. This function has been implicitly getting the
+ current running loop since 3.7. See
+ :ref:`What's New in 3.10's Removed section `
+ for more information.
+
.. _asyncio_example_sleep:
Example of coroutine displaying the current date every second
@@ -317,6 +330,10 @@ Sleeping
asyncio.run(display_date())
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
+
Running Tasks Concurrently
==========================
@@ -349,6 +366,9 @@ Running Tasks Concurrently
cancellation of one submitted Task/Future to cause other
Tasks/Futures to be cancelled.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. _asyncio_example_gather:
Example::
@@ -358,32 +378,35 @@ Running Tasks Concurrently
async def factorial(name, number):
f = 1
for i in range(2, number + 1):
- print(f"Task {name}: Compute factorial({i})...")
+ print(f"Task {name}: Compute factorial({number}), currently i={i}...")
await asyncio.sleep(1)
f *= i
print(f"Task {name}: factorial({number}) = {f}")
+ return f
async def main():
# Schedule three calls *concurrently*:
- await asyncio.gather(
+ L = await asyncio.gather(
factorial("A", 2),
factorial("B", 3),
factorial("C", 4),
)
+ print(L)
asyncio.run(main())
# Expected output:
#
- # Task A: Compute factorial(2)...
- # Task B: Compute factorial(2)...
- # Task C: Compute factorial(2)...
+ # Task A: Compute factorial(2), currently i=2...
+ # Task B: Compute factorial(3), currently i=2...
+ # Task C: Compute factorial(4), currently i=2...
# Task A: factorial(2) = 2
- # Task B: Compute factorial(3)...
- # Task C: Compute factorial(3)...
+ # Task B: Compute factorial(3), currently i=3...
+ # Task C: Compute factorial(4), currently i=3...
# Task B: factorial(3) = 6
- # Task C: Compute factorial(4)...
+ # Task C: Compute factorial(4), currently i=4...
# Task C: factorial(4) = 24
+ # [2, 6, 24]
.. note::
If *return_exceptions* is False, cancelling gather() after it
@@ -397,6 +420,9 @@ Running Tasks Concurrently
If the *gather* itself is cancelled, the cancellation is
propagated regardless of *return_exceptions*.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. deprecated:: 3.10
Deprecation warning is emitted if no positional arguments are provided
or not all positional arguments are Future-like objects
@@ -439,6 +465,9 @@ Shielding From Cancellation
except CancelledError:
res = None
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. deprecated:: 3.10
Deprecation warning is emitted if *aw* is not Future-like object
and there is no running event loop.
@@ -470,6 +499,9 @@ Timeouts
If the wait is cancelled, the future *aw* is also cancelled.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. _asyncio_example_waitfor:
Example::
@@ -497,6 +529,9 @@ Timeouts
for *aw* to be cancelled. Previously, it raised
:exc:`asyncio.TimeoutError` immediately.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
Waiting Primitives
==================
@@ -553,6 +588,9 @@ Waiting Primitives
``wait()`` directly is deprecated as it leads to
:ref:`confusing behavior `.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. _asyncio_example_wait_coroutine:
.. note::
@@ -585,6 +623,9 @@ Waiting Primitives
Passing coroutine objects to ``wait()`` directly is
deprecated.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. function:: as_completed(aws, *, timeout=None)
@@ -596,12 +637,18 @@ Waiting Primitives
Raises :exc:`asyncio.TimeoutError` if the timeout occurs before
all Futures are done.
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
Example::
for coro in as_completed(aws):
earliest_result = await coro
# ...
+ .. versionchanged:: 3.10
+ Removed the *loop* parameter.
+
.. deprecated:: 3.10
Deprecation warning is emitted if not all awaitable objects in the *aws*
iterable are Future-like objects and there is no running event loop.
@@ -694,7 +741,7 @@ Scheduling From Other Threads
try:
result = future.result(timeout)
- except asyncio.TimeoutError:
+ except concurrent.futures.TimeoutError:
print('The coroutine took too long, cancelling the task...')
future.cancel()
except Exception as exc:
@@ -783,10 +830,7 @@ Task Object
Added support for the :mod:`contextvars` module.
.. versionchanged:: 3.8
- Added the ``name`` parameter.
-
- .. deprecated-removed:: 3.8 3.10
- The *loop* parameter.
+ Added the *name* parameter.
.. deprecated:: 3.10
Deprecation warning is emitted if *loop* is not specified
@@ -808,7 +852,7 @@ Task Object
discouraged.
.. versionchanged:: 3.9
- Added the ``msg`` parameter.
+ Added the *msg* parameter.
.. _asyncio_example_task_cancel:
@@ -980,7 +1024,7 @@ Generator-based Coroutines
.. note::
Support for generator-based coroutines is **deprecated** and
- is scheduled for removal in Python 3.10.
+ is removed in Python 3.11.
Generator-based coroutines predate async/await syntax. They are
Python generators that use ``yield from`` expressions to await
@@ -1008,7 +1052,7 @@ enforced.
This decorator should not be used for :keyword:`async def`
coroutines.
- .. deprecated-removed:: 3.8 3.10
+ .. deprecated-removed:: 3.8 3.11
Use :keyword:`async def` instead.
diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst
index 94a853259d3483..a6429394389b10 100644
--- a/Doc/library/asyncio.rst
+++ b/Doc/library/asyncio.rst
@@ -17,7 +17,6 @@
await asyncio.sleep(1)
print('... World!')
- # Python 3.7+
asyncio.run(main())
asyncio is a library to write **concurrent** code using
diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst
index a86518ebff2777..a732fd7ba4f152 100644
--- a/Doc/library/asyncore.rst
+++ b/Doc/library/asyncore.rst
@@ -4,6 +4,7 @@
.. module:: asyncore
:synopsis: A base class for developing asynchronous socket handling
services.
+ :deprecated:
.. moduleauthor:: Sam Rushing
.. sectionauthor:: Christopher Petrilli
@@ -13,6 +14,8 @@
**Source code:** :source:`Lib/asyncore.py`
.. deprecated:: 3.6
+ :mod:`asyncore` will be removed in Python 3.12
+ (see :pep:`PEP 594 <594#asyncore>` for details).
Please use :mod:`asyncio` instead.
--------------
diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst
index c2c058e474cbdc..f7f038107d11fe 100644
--- a/Doc/library/atexit.rst
+++ b/Doc/library/atexit.rst
@@ -39,7 +39,7 @@ internal error is detected, or when :func:`os._exit` is called.
If an exception is raised during execution of the exit handlers, a traceback is
printed (unless :exc:`SystemExit` is raised) and the exception information is
- saved. After all exit handlers have had a chance to run the last exception to
+ saved. After all exit handlers have had a chance to run, the last exception to
be raised is re-raised.
This function returns *func*, which makes it possible to use it as a
@@ -48,11 +48,12 @@ internal error is detected, or when :func:`os._exit` is called.
.. function:: unregister(func)
- Remove *func* from the list of functions to be run at interpreter
- shutdown. After calling :func:`unregister`, *func* is guaranteed not to be
- called when the interpreter shuts down, even if it was registered more than
- once. :func:`unregister` silently does nothing if *func* was not previously
- registered.
+ Remove *func* from the list of functions to be run at interpreter shutdown.
+ :func:`unregister` silently does nothing if *func* was not previously
+ registered. If *func* has been registered more than once, every occurrence
+ of that function in the :mod:`atexit` call stack will be removed. Equality
+ comparisons (``==``) are used internally during unregistration, so function
+ references do not need to have matching identities.
.. seealso::
@@ -73,7 +74,7 @@ automatically when the program terminates without relying on the application
making an explicit call into this module at termination. ::
try:
- with open("counterfile") as infile:
+ with open('counterfile') as infile:
_count = int(infile.read())
except FileNotFoundError:
_count = 0
@@ -83,21 +84,22 @@ making an explicit call into this module at termination. ::
_count = _count + n
def savecounter():
- with open("counterfile", "w") as outfile:
- outfile.write("%d" % _count)
+ with open('counterfile', 'w') as outfile:
+ outfile.write('%d' % _count)
import atexit
+
atexit.register(savecounter)
Positional and keyword arguments may also be passed to :func:`register` to be
passed along to the registered function when it is called::
def goodbye(name, adjective):
- print('Goodbye, %s, it was %s to meet you.' % (name, adjective))
+ print('Goodbye %s, it was %s to meet you.' % (name, adjective))
import atexit
- atexit.register(goodbye, 'Donny', 'nice')
+ atexit.register(goodbye, 'Donny', 'nice')
# or:
atexit.register(goodbye, adjective='nice', name='Donny')
@@ -107,6 +109,6 @@ Usage as a :term:`decorator`::
@atexit.register
def goodbye():
- print("You are now leaving the Python sector.")
+ print('You are now leaving the Python sector.')
This only works with functions that can be called without arguments.
diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst
index bad9da2ec62e56..649c99e796282c 100644
--- a/Doc/library/audioop.rst
+++ b/Doc/library/audioop.rst
@@ -3,6 +3,11 @@
.. module:: audioop
:synopsis: Manipulate raw audio data.
+ :deprecated:
+
+.. deprecated:: 3.11
+ The :mod:`audioop` module is deprecated
+ (see :pep:`PEP 594 <594#audioop>` for details).
--------------
diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst
index 2f24bb63912fb6..f1063a78d9665d 100644
--- a/Doc/library/base64.rst
+++ b/Doc/library/base64.rst
@@ -2,7 +2,7 @@
===============================================================
.. module:: base64
- :synopsis: RFC 3548: Base16, Base32, Base64 Data Encodings;
+ :synopsis: RFC 4648: Base16, Base32, Base64 Data Encodings;
Base85 and Ascii85
**Source code:** :source:`Lib/base64.py`
@@ -16,10 +16,10 @@
This module provides functions for encoding binary data to printable
ASCII characters and decoding such encodings back to binary data.
It provides encoding and decoding functions for the encodings specified in
-:rfc:`3548`, which defines the Base16, Base32, and Base64 algorithms,
+:rfc:`4648`, which defines the Base16, Base32, and Base64 algorithms,
and for the de-facto standard Ascii85 and Base85 encodings.
-The :rfc:`3548` encodings are suitable for encoding binary data so that it can
+The :rfc:`4648` encodings are suitable for encoding binary data so that it can be
safely sent by email, used as parts of URLs, or included as part of an HTTP
POST request. The encoding algorithm is not the same as the
:program:`uuencode` program.
@@ -28,7 +28,7 @@ There are two interfaces provided by this module. The modern interface
supports encoding :term:`bytes-like objects ` to ASCII
:class:`bytes`, and decoding :term:`bytes-like objects ` or
strings containing ASCII to :class:`bytes`. Both base-64 alphabets
-defined in :rfc:`3548` (normal, and URL- and filesystem-safe) are supported.
+defined in :rfc:`4648` (normal, and URL- and filesystem-safe) are supported.
The legacy interface does not support decoding from strings, but it does
provide functions for encoding and decoding to and from :term:`file objects
@@ -152,7 +152,7 @@ The modern interface provides:
This version does not allow the digit 0 (zero) to the letter O (oh) and digit
1 (one) to either the letter I (eye) or letter L (el) mappings, all these
characters are included in the Extended Hex Alphabet and are not
- interchangable.
+ interchangeable.
.. versionadded:: 3.10
@@ -199,7 +199,7 @@ The modern interface provides:
.. 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')
Decode the Ascii85 encoded :term:`bytes-like object` or ASCII string *b* and
return the decoded :class:`bytes`.
@@ -287,6 +287,13 @@ An example usage of the module:
>>> data
b'data to be encoded'
+.. _base64-security:
+
+Security Considerations
+-----------------------
+
+A new security considerations section was added to :rfc:`4648` (section 12); it's
+recommended to review the security section for any code deployed to production.
.. seealso::
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 2c0c1bce5d7f8f..5cd058c0b6d74f 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -135,7 +135,7 @@ The :mod:`binascii` module defines the following functions:
.. function:: crc32(data[, value])
- Compute CRC-32, the 32-bit checksum of *data*, starting with an
+ Compute CRC-32, the unsigned 32-bit checksum of *data*, starting with an
initial CRC of *value*. The default initial CRC is zero. The algorithm
is consistent with the ZIP file checksum. Since the algorithm is designed for
use as a checksum algorithm, it is not suitable for use as a general hash
@@ -149,9 +149,8 @@ The :mod:`binascii` module defines the following functions:
.. versionchanged:: 3.0
The result is always unsigned.
- To generate the same numeric value across all Python versions and
- platforms, use ``crc32(data) & 0xffffffff``.
-
+ To generate the same numeric value when using Python 2 or earlier,
+ use ``crc32(data) & 0xffffffff``.
.. function:: b2a_hex(data[, sep[, bytes_per_sep=1]])
hexlify(data[, sep[, bytes_per_sep=1]])
diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst
index f34ee175ba6574..513675d3685a52 100644
--- a/Doc/library/bisect.rst
+++ b/Doc/library/bisect.rst
@@ -35,15 +35,18 @@ The following functions are provided:
``all(val >= x for val in a[i : hi])`` for the right side.
*key* specifies a :term:`key function` of one argument that is used to
- extract a comparison key from each input element. The default value is
- ``None`` (compare the elements directly).
+ extract a comparison key from each element in the array. To support
+ searching complex records, the key function is not applied to the *x* value.
+
+ If *key* is ``None``, the elements are compared directly with no
+ intervening function call.
.. versionchanged:: 3.10
Added the *key* parameter.
.. function:: bisect_right(a, x, lo=0, hi=len(a), *, key=None)
- bisect(a, x, lo=0, hi=len(a))
+ bisect(a, x, lo=0, hi=len(a), *, key=None)
Similar to :func:`bisect_left`, but returns an insertion point which comes
after (to the right of) any existing entries of *x* in *a*.
@@ -53,8 +56,11 @@ The following functions are provided:
``all(val > x for val in a[i : hi])`` for the right side.
*key* specifies a :term:`key function` of one argument that is used to
- extract a comparison key from each input element. The default value is
- ``None`` (compare the elements directly).
+ extract a comparison key from each element in the array. To support
+ searching complex records, the key function is not applied to the *x* value.
+
+ If *key* is ``None``, the elements are compared directly with no
+ intervening function call.
.. versionchanged:: 3.10
Added the *key* parameter.
@@ -64,14 +70,13 @@ The following functions are provided:
Insert *x* in *a* in sorted order.
- *key* specifies a :term:`key function` of one argument that is used to
- extract a comparison key from each input element. The default value is
- ``None`` (compare the elements directly).
-
This function first runs :func:`bisect_left` to locate an insertion point.
Next, it runs the :meth:`insert` method on *a* to insert *x* at the
appropriate position to maintain sort order.
+ To support inserting records in a table, the *key* function (if any) is
+ applied to *x* for the search step but not for the insertion step.
+
Keep in mind that the ``O(log n)`` search is dominated by the slow O(n)
insertion step.
@@ -80,19 +85,18 @@ The following functions are provided:
.. function:: insort_right(a, x, lo=0, hi=len(a), *, key=None)
- insort(a, x, lo=0, hi=len(a))
+ insort(a, x, lo=0, hi=len(a), *, key=None)
Similar to :func:`insort_left`, but inserting *x* in *a* after any existing
entries of *x*.
- *key* specifies a :term:`key function` of one argument that is used to
- extract a comparison key from each input element. The default value is
- ``None`` (compare the elements directly).
-
This function first runs :func:`bisect_right` to locate an insertion point.
Next, it runs the :meth:`insert` method on *a* to insert *x* at the
appropriate position to maintain sort order.
+ To support inserting records in a table, the *key* function (if any) is
+ applied to *x* for the search step but not for the insertion step.
+
Keep in mind that the ``O(log n)`` search is dominated by the slow O(n)
insertion step.
@@ -194,8 +198,42 @@ a 'B', and so on::
>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
-One technique to avoid repeated calls to a key function is to search a list of
-precomputed keys to find the index of a record::
+The :func:`bisect` and :func:`insort` functions also work with lists of
+tuples. The *key* argument can serve to extract the field used for ordering
+records in a table::
+
+ >>> from collections import namedtuple
+ >>> from operator import attrgetter
+ >>> from bisect import bisect, insort
+ >>> from pprint import pprint
+
+ >>> Movie = namedtuple('Movie', ('name', 'released', 'director'))
+
+ >>> movies = [
+ ... Movie('Jaws', 1975, 'Speilberg'),
+ ... Movie('Titanic', 1997, 'Cameron'),
+ ... Movie('The Birds', 1963, 'Hitchcock'),
+ ... Movie('Aliens', 1986, 'Scott')
+ ... ]
+
+ >>> # Find the first movie released on or after 1960
+ >>> by_year = attrgetter('released')
+ >>> movies.sort(key=by_year)
+ >>> movies[bisect(movies, 1960, key=by_year)]
+ Movie(name='The Birds', released=1963, director='Hitchcock')
+
+ >>> # Insert a movie while maintaining sort order
+ >>> romance = Movie('Love Story', 1970, 'Hiller')
+ >>> insort(movies, romance, key=by_year)
+ >>> pprint(movies)
+ [Movie(name='The Birds', released=1963, director='Hitchcock'),
+ Movie(name='Love Story', released=1970, director='Hiller'),
+ Movie(name='Jaws', released=1975, director='Speilberg'),
+ Movie(name='Aliens', released=1986, director='Scott'),
+ Movie(name='Titanic', released=1997, director='Cameron')]
+
+If the key function is expensive, it is possible to avoid repeated function
+calls by searching a list of precomputed keys to find the index of a record::
>>> data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
>>> data.sort(key=lambda r: r[1]) # Or use operator.itemgetter(1).
@@ -208,4 +246,3 @@ precomputed keys to find the index of a record::
('red', 5)
>>> data[bisect_left(keys, 8)]
('yellow', 8)
-
diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst
index f6787ab120ed57..999892e95f4715 100644
--- a/Doc/library/bz2.rst
+++ b/Doc/library/bz2.rst
@@ -325,3 +325,8 @@ Writing and reading a bzip2-compressed file in binary mode:
... content = f.read()
>>> content == data # Check equality to original object after round-trip
True
+
+.. testcleanup::
+
+ import os
+ os.remove("myfile.bz2")
diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst
index c3c04db853ed2d..f641760d1bd1a9 100644
--- a/Doc/library/calendar.rst
+++ b/Doc/library/calendar.rst
@@ -31,7 +31,7 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
.. class:: Calendar(firstweekday=0)
Creates a :class:`Calendar` object. *firstweekday* is an integer specifying the
- first day of the week. ``0`` is Monday (the default), ``6`` is Sunday.
+ first day of the week. :const:`MONDAY` is ``0`` (the default), :const:`SUNDAY` is ``6``.
A :class:`Calendar` object provides several methods that can be used for
preparing the calendar data for formatting. This class doesn't do any formatting
@@ -409,6 +409,15 @@ The :mod:`calendar` module exports the following data attributes:
locale. This follows normal convention of January being month number 1, so it
has a length of 13 and ``month_abbr[0]`` is the empty string.
+.. data:: MONDAY
+ TUESDAY
+ WEDNESDAY
+ THURSDAY
+ FRIDAY
+ SATURDAY
+ SUNDAY
+
+ Aliases for day numbers, where ``MONDAY`` is ``0`` and ``SUNDAY`` is ``6``.
.. seealso::
diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst
index 05d9cdf424073f..eeb80ed57ef35d 100644
--- a/Doc/library/cgi.rst
+++ b/Doc/library/cgi.rst
@@ -3,6 +3,7 @@
.. module:: cgi
:synopsis: Helpers for running Python scripts via the Common Gateway Interface.
+ :deprecated:
**Source code:** :source:`Lib/cgi.py`
@@ -14,6 +15,10 @@
single: URL
single: Common Gateway Interface
+.. deprecated:: 3.11
+ The :mod:`cgi` module is deprecated
+ (see :pep:`PEP 594 <594#cgi>` for details and alternatives).
+
--------------
Support module for Common Gateway Interface (CGI) scripts.
@@ -73,7 +78,7 @@ When you write a new script, consider adding these lines::
cgitb.enable()
This activates a special exception handler that will display detailed reports in
-the Web browser if any errors occur. If you'd rather not show the guts of your
+the web browser if any errors occur. If you'd rather not show the guts of your
program to users of your script, you can have the reports saved to files
instead, with code like this::
@@ -89,7 +94,7 @@ To get at submitted form data, use the :class:`FieldStorage` class. If the form
contains non-ASCII characters, use the *encoding* keyword parameter set to the
value of the encoding defined for the document. It is usually contained in the
META tag in the HEAD section of the HTML document or by the
-:mailheader:`Content-Type` header). This reads the form contents from the
+:mailheader:`Content-Type` header. This reads the form contents from the
standard input or the environment (depending on the value of various
environment variables set according to the CGI standard). Since it may consume
standard input, it should be instantiated only once.
@@ -316,7 +321,7 @@ algorithms implemented in this module in other circumstances.
.. function:: test()
Robust test CGI script, usable as main program. Writes minimal HTTP headers and
- formats all information provided to the script in HTML form.
+ formats all information provided to the script in HTML format.
.. function:: print_environ()
@@ -346,11 +351,11 @@ Caring about security
.. index:: pair: CGI; security
-There's one important rule: if you invoke an external program (via the
-:func:`os.system` or :func:`os.popen` functions. or others with similar
+There's one important rule: if you invoke an external program (via
+:func:`os.system`, :func:`os.popen` or other functions with similar
functionality), make very sure you don't pass arbitrary strings received from
the client to the shell. This is a well-known security hole whereby clever
-hackers anywhere on the Web can exploit a gullible CGI script to invoke
+hackers anywhere on the web can exploit a gullible CGI script to invoke
arbitrary shell commands. Even parts of the URL or field names cannot be
trusted, since the request doesn't have to come from your form!
@@ -424,7 +429,7 @@ above on installing your CGI script carefully can save you a lot of time. If
you wonder whether you have understood the installation procedure correctly, try
installing a copy of this module file (:file:`cgi.py`) as a CGI script. When
invoked as a script, the file will dump its environment and the contents of the
-form in HTML form. Give it the right mode etc, and send it a request. If it's
+form in HTML format. Give it the right mode etc., and send it a request. If it's
installed in the standard :file:`cgi-bin` directory, it should be possible to
send it a request by entering a URL into your browser of the form:
@@ -457,7 +462,7 @@ likely the traceback will end up in one of the HTTP server's log files, or be
discarded altogether.
Fortunately, once you have managed to get your script to execute *some* code,
-you can easily send tracebacks to the Web browser using the :mod:`cgitb` module.
+you can easily send tracebacks to the web browser using the :mod:`cgitb` module.
If you haven't done so already, just add the lines::
import cgitb
diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst
index 5f3a6476dd8cdc..3b0b106abacd50 100644
--- a/Doc/library/cgitb.rst
+++ b/Doc/library/cgitb.rst
@@ -3,6 +3,7 @@
.. module:: cgitb
:synopsis: Configurable traceback handler for CGI scripts.
+ :deprecated:
.. moduleauthor:: Ka-Ping Yee
.. sectionauthor:: Fred L. Drake, Jr.
@@ -15,6 +16,10 @@
single: exceptions; in CGI scripts
single: tracebacks; in CGI scripts
+.. deprecated:: 3.11
+ The :mod:`cgitb` module is deprecated
+ (see :pep:`PEP 594 <594#cgitb>` for details).
+
--------------
The :mod:`cgitb` module provides a special exception handler for Python scripts.
diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst
index 5e24df923ed210..5a84c8904f7145 100644
--- a/Doc/library/chunk.rst
+++ b/Doc/library/chunk.rst
@@ -3,6 +3,7 @@
.. module:: chunk
:synopsis: Module to read IFF chunks.
+ :deprecated:
.. moduleauthor:: Sjoerd Mullender
.. sectionauthor:: Sjoerd Mullender
@@ -16,6 +17,10 @@
single: Real Media File Format
single: RMFF
+.. deprecated:: 3.11
+ The :mod:`chunk` module is deprecated
+ (see :pep:`PEP 594 <594#chunk>` for details).
+
--------------
This module provides an interface for reading files that use EA IFF 85 chunks.
diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst
index 0dcd88f9fd5b7f..1c10462c1509c3 100644
--- a/Doc/library/codecs.rst
+++ b/Doc/library/codecs.rst
@@ -23,11 +23,11 @@
This module defines base classes for standard Python codecs (encoders and
decoders) and provides access to the internal Python codec registry, which
manages the codec and error handling lookup process. Most standard codecs
-are :term:`text encodings `, which encode text to bytes,
-but there are also codecs provided that encode text to text, and bytes to
-bytes. Custom codecs may encode and decode between arbitrary types, but some
-module features are restricted to use specifically with
-:term:`text encodings `, or with codecs that encode to
+are :term:`text encodings `, which encode text to bytes (and
+decode bytes to text), but there are also codecs provided that encode text to
+text, and bytes to bytes. Custom codecs may encode and decode between arbitrary
+types, but some module features are restricted to be used specifically with
+:term:`text encodings ` or with codecs that encode to
:class:`bytes`.
The module defines the following functions for encoding and decoding with
@@ -297,58 +297,56 @@ codec will handle encoding and decoding errors.
Error Handlers
^^^^^^^^^^^^^^
-To simplify and standardize error handling,
-codecs may implement different error handling schemes by
-accepting the *errors* string argument. The following string values are
-defined and implemented by all standard Python codecs:
+To simplify and standardize error handling, codecs may implement different
+error handling schemes by accepting the *errors* string argument:
-.. tabularcolumns:: |l|L|
-
-+-------------------------+-----------------------------------------------+
-| Value | Meaning |
-+=========================+===============================================+
-| ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass); |
-| | this is the default. Implemented in |
-| | :func:`strict_errors`. |
-+-------------------------+-----------------------------------------------+
-| ``'ignore'`` | Ignore the malformed data and continue |
-| | without further notice. Implemented in |
-| | :func:`ignore_errors`. |
-+-------------------------+-----------------------------------------------+
-
-The following error handlers are only applicable to
-:term:`text encodings `:
+ >>> 'German ß, ♬'.encode(encoding='ascii', errors='backslashreplace')
+ b'German \\xdf, \\u266c'
+ >>> 'German ß, ♬'.encode(encoding='ascii', errors='xmlcharrefreplace')
+ b'German ß, ♬'
.. index::
+ pair: strict; error handler's name
+ pair: ignore; error handler's name
+ pair: replace; error handler's name
+ pair: backslashreplace; error handler's name
+ pair: surrogateescape; error handler's name
single: ? (question mark); replacement character
single: \ (backslash); escape sequence
single: \x; escape sequence
single: \u; escape sequence
single: \U; escape sequence
- single: \N; escape sequence
+
+The following error handlers can be used with all Python
+:ref:`standard-encodings` codecs:
+
+.. tabularcolumns:: |l|L|
+-------------------------+-----------------------------------------------+
| Value | Meaning |
+=========================+===============================================+
-| ``'replace'`` | Replace with a suitable replacement |
-| | marker; Python will use the official |
-| | ``U+FFFD`` REPLACEMENT CHARACTER for the |
-| | built-in codecs on decoding, and '?' on |
-| | encoding. Implemented in |
-| | :func:`replace_errors`. |
+| ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass), |
+| | this is the default. Implemented in |
+| | :func:`strict_errors`. |
+-------------------------+-----------------------------------------------+
-| ``'xmlcharrefreplace'`` | Replace with the appropriate XML character |
-| | reference (only for encoding). Implemented |
-| | in :func:`xmlcharrefreplace_errors`. |
+| ``'ignore'`` | Ignore the malformed data and continue without|
+| | further notice. Implemented in |
+| | :func:`ignore_errors`. |
++-------------------------+-----------------------------------------------+
+| ``'replace'`` | Replace with a replacement marker. On |
+| | encoding, use ``?`` (ASCII character). On |
+| | decoding, use ``�`` (U+FFFD, the official |
+| | REPLACEMENT CHARACTER). Implemented in |
+| | :func:`replace_errors`. |
+-------------------------+-----------------------------------------------+
| ``'backslashreplace'`` | Replace with backslashed escape sequences. |
+| | On encoding, use hexadecimal form of Unicode |
+| | code point with formats ``\xhh`` ``\uxxxx`` |
+| | ``\Uxxxxxxxx``. On decoding, use hexadecimal |
+| | form of byte value with format ``\xhh``. |
| | Implemented in |
| | :func:`backslashreplace_errors`. |
+-------------------------+-----------------------------------------------+
-| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences |
-| | (only for encoding). Implemented in |
-| | :func:`namereplace_errors`. |
-+-------------------------+-----------------------------------------------+
| ``'surrogateescape'`` | On decoding, replace byte with individual |
| | surrogate code ranging from ``U+DC80`` to |
| | ``U+DCFF``. This code will then be turned |
@@ -358,27 +356,55 @@ The following error handlers are only applicable to
| | more.) |
+-------------------------+-----------------------------------------------+
+.. index::
+ pair: xmlcharrefreplace; error handler's name
+ pair: namereplace; error handler's name
+ single: \N; escape sequence
+
+The following error handlers are only applicable to encoding (within
+:term:`text encodings `):
+
++-------------------------+-----------------------------------------------+
+| Value | Meaning |
++=========================+===============================================+
+| ``'xmlcharrefreplace'`` | Replace with XML/HTML numeric character |
+| | reference, which is a decimal form of Unicode |
+| | code point with format ``num;`` Implemented |
+| | in :func:`xmlcharrefreplace_errors`. |
++-------------------------+-----------------------------------------------+
+| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences, |
+| | what appears in the braces is the Name |
+| | property from Unicode Character Database. |
+| | Implemented in :func:`namereplace_errors`. |
++-------------------------+-----------------------------------------------+
+
+.. index::
+ pair: surrogatepass; error handler's name
+
In addition, the following error handler is specific to the given codecs:
+-------------------+------------------------+-------------------------------------------+
| Value | Codecs | Meaning |
+===================+========================+===========================================+
-|``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding of surrogate |
-| | utf-16-be, utf-16-le, | codes. These codecs normally treat the |
-| | utf-32-be, utf-32-le | presence of surrogates as an error. |
+|``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding surrogate code|
+| | utf-16-be, utf-16-le, | point (``U+D800`` - ``U+DFFF``) as normal |
+| | utf-32-be, utf-32-le | code point. Otherwise these codecs treat |
+| | | the presence of surrogate code point in |
+| | | :class:`str` as an error. |
+-------------------+------------------------+-------------------------------------------+
.. versionadded:: 3.1
The ``'surrogateescape'`` and ``'surrogatepass'`` error handlers.
.. versionchanged:: 3.4
- The ``'surrogatepass'`` error handlers now works with utf-16\* and utf-32\* codecs.
+ The ``'surrogatepass'`` error handler now works with utf-16\* and utf-32\*
+ codecs.
.. versionadded:: 3.5
The ``'namereplace'`` error handler.
.. versionchanged:: 3.5
- The ``'backslashreplace'`` error handlers now works with decoding and
+ The ``'backslashreplace'`` error handler now works with decoding and
translating.
The set of allowed values can be extended by registering a new named error
@@ -421,42 +447,59 @@ functions:
.. function:: strict_errors(exception)
- Implements the ``'strict'`` error handling: each encoding or
- decoding error raises a :exc:`UnicodeError`.
+ Implements the ``'strict'`` error handling.
+ Each encoding or decoding error raises a :exc:`UnicodeError`.
-.. function:: replace_errors(exception)
- Implements the ``'replace'`` error handling (for :term:`text encodings
- ` only): substitutes ``'?'`` for encoding errors
- (to be encoded by the codec), and ``'\ufffd'`` (the Unicode replacement
- character) for decoding errors.
+.. function:: ignore_errors(exception)
+ Implements the ``'ignore'`` error handling.
-.. function:: ignore_errors(exception)
+ Malformed data is ignored; encoding or decoding is continued without
+ further notice.
- Implements the ``'ignore'`` error handling: malformed data is ignored and
- encoding or decoding is continued without further notice.
+.. function:: replace_errors(exception)
-.. function:: xmlcharrefreplace_errors(exception)
+ Implements the ``'replace'`` error handling.
- Implements the ``'xmlcharrefreplace'`` error handling (for encoding with
- :term:`text encodings ` only): the
- unencodable character is replaced by an appropriate XML character reference.
+ Substitutes ``?`` (ASCII character) for encoding errors or ``�`` (U+FFFD,
+ the official REPLACEMENT CHARACTER) for decoding errors.
.. function:: backslashreplace_errors(exception)
- Implements the ``'backslashreplace'`` error handling (for
- :term:`text encodings ` only): malformed data is
- replaced by a backslashed escape sequence.
+ Implements the ``'backslashreplace'`` error handling.
+
+ Malformed data is replaced by a backslashed escape sequence.
+ On encoding, use the hexadecimal form of Unicode code point with formats
+ ``\xhh`` ``\uxxxx`` ``\Uxxxxxxxx``. On decoding, use the hexadecimal form of
+ byte value with format ``\xhh``.
+
+ .. versionchanged:: 3.5
+ Works with decoding and translating.
+
+
+.. function:: xmlcharrefreplace_errors(exception)
+
+ Implements the ``'xmlcharrefreplace'`` error handling (for encoding within
+ :term:`text encoding` only).
+
+ The unencodable character is replaced by an appropriate XML/HTML numeric
+ character reference, which is a decimal form of Unicode code point with
+ format ``num;`` .
+
.. function:: namereplace_errors(exception)
- Implements the ``'namereplace'`` error handling (for encoding with
- :term:`text encodings ` only): the
- unencodable character is replaced by a ``\N{...}`` escape sequence.
+ Implements the ``'namereplace'`` error handling (for encoding within
+ :term:`text encoding` only).
+
+ The unencodable character is replaced by a ``\N{...}`` escape sequence. The
+ set of characters that appear in the braces is the Name property from
+ Unicode Character Database. For example, the German lowercase letter ``'ß'``
+ will be converted to byte sequence ``\N{LATIN SMALL LETTER SHARP S}`` .
.. versionadded:: 3.5
@@ -470,7 +513,7 @@ The base :class:`Codec` class defines these methods which also define the
function interfaces of the stateless encoder and decoder:
-.. method:: Codec.encode(input[, errors])
+.. method:: Codec.encode(input, errors='strict')
Encodes the object *input* and returns a tuple (output object, length consumed).
For instance, :term:`text encoding` converts
@@ -488,7 +531,7 @@ function interfaces of the stateless encoder and decoder:
of the output object type in this situation.
-.. method:: Codec.decode(input[, errors])
+.. method:: Codec.decode(input, errors='strict')
Decodes the object *input* and returns a tuple (output object, length
consumed). For instance, for a :term:`text encoding`, decoding converts
@@ -555,7 +598,7 @@ define in order to be compatible with the Python codec registry.
object.
- .. method:: encode(object[, final])
+ .. method:: encode(object, final=False)
Encodes *object* (taking the current state of the encoder into account)
and returns the resulting encoded object. If this is the last call to
@@ -612,7 +655,7 @@ define in order to be compatible with the Python codec registry.
object.
- .. method:: decode(object[, final])
+ .. method:: decode(object, final=False)
Decodes *object* (taking the current state of the decoder into account)
and returns the resulting decoded object. If this is the last call to
@@ -694,8 +737,9 @@ compatible with the Python codec registry.
.. method:: writelines(list)
- Writes the concatenated list of strings to the stream (possibly by reusing
- the :meth:`write` method). The standard bytes-to-bytes codecs
+ Writes the concatenated iterable of strings to the stream (possibly by reusing
+ the :meth:`write` method). Infinite or
+ very large iterables are not supported. The standard bytes-to-bytes codecs
do not support this method.
@@ -745,7 +789,7 @@ compatible with the Python codec registry.
:func:`register_error`.
- .. method:: read([size[, chars, [firstline]]])
+ .. method:: read(size=-1, chars=-1, firstline=False)
Decodes data from the stream and returns the resulting object.
@@ -771,7 +815,7 @@ compatible with the Python codec registry.
available on the stream, these should be read too.
- .. method:: readline([size[, keepends]])
+ .. method:: readline(size=None, keepends=True)
Read one line from the input stream and return the decoded data.
@@ -782,7 +826,7 @@ compatible with the Python codec registry.
returned.
- .. method:: readlines([sizehint[, keepends]])
+ .. method:: readlines(sizehint=None, keepends=True)
Read all lines available on the input stream and return them as a list of
lines.
@@ -873,7 +917,7 @@ Encodings and Unicode
---------------------
Strings are stored internally as sequences of code points in
-range ``0x0``--``0x10FFFF``. (See :pep:`393` for
+range ``U+0000``--``U+10FFFF``. (See :pep:`393` for
more details about the implementation.)
Once a string object is used outside of CPU and memory, endianness
and how these arrays are stored as bytes become an issue. As with other
@@ -911,7 +955,7 @@ there's the so called BOM ("Byte Order Mark"). This is the Unicode character
``U+FEFF``. This character can be prepended to every ``UTF-16`` or ``UTF-32``
byte sequence. The byte swapped version of this character (``0xFFFE``) is an
illegal character that may not appear in a Unicode text. So when the
-first character in an ``UTF-16`` or ``UTF-32`` byte sequence
+first character in a ``UTF-16`` or ``UTF-32`` byte sequence
appears to be a ``U+FFFE`` the bytes have to be swapped on decoding.
Unfortunately the character ``U+FEFF`` had a second purpose as
a ``ZERO WIDTH NO-BREAK SPACE``: a character that has no width and doesn't allow
@@ -923,7 +967,7 @@ it's a device to determine the storage layout of the encoded bytes, and vanishes
once the byte sequence has been decoded into a string; as a ``ZERO WIDTH
NO-BREAK SPACE`` it's a normal character that will be decoded like any other.
-There's another encoding that is able to encoding the full range of Unicode
+There's another encoding that is able to encode the full range of Unicode
characters: UTF-8. UTF-8 is an 8-bit encoding, which means there are no issues
with byte order in UTF-8. Each byte in a UTF-8 byte sequence consists of two
parts: marker bits (the most significant bits) and payload bits. The marker bits
@@ -954,7 +998,7 @@ encoding was used for encoding a string. Each charmap encoding can
decode any random byte sequence. However that's not possible with UTF-8, as
UTF-8 byte sequences have a structure that doesn't allow arbitrary byte
sequences. To increase the reliability with which a UTF-8 encoding can be
-detected, Microsoft invented a variant of UTF-8 (that Python 2.5 calls
+detected, Microsoft invented a variant of UTF-8 (that Python calls
``"utf-8-sig"``) for its Notepad program: Before any of the Unicode characters
is written to the file, a UTF-8 encoded BOM (which looks like this as a byte
sequence: ``0xef``, ``0xbb``, ``0xbf``) is written. As it's rather improbable
@@ -1422,7 +1466,7 @@ Internationalized Domain Names (IDN)). It builds upon the ``punycode`` encoding
and :mod:`stringprep`.
If you need the IDNA 2008 standard from :rfc:`5891` and :rfc:`5895`, use the
-third-party `idna module _`.
+third-party `idna module `_.
These RFCs together define a protocol to support non-ASCII characters in domain
names. A domain name containing non-ASCII characters (such as
diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst
index 2345e78a17e4f5..2c941b47748d36 100644
--- a/Doc/library/collections.abc.rst
+++ b/Doc/library/collections.abc.rst
@@ -14,7 +14,7 @@
.. testsetup:: *
- from collections import *
+ from collections.abc import *
import itertools
__name__ = ''
@@ -24,6 +24,89 @@ This module provides :term:`abstract base classes ` that
can be used to test whether a class provides a particular interface; for
example, whether it is hashable or whether it is a mapping.
+An :func:`issubclass` or :func:`isinstance` test for an interface works in one
+of three ways.
+
+1) A newly written class can inherit directly from one of the
+abstract base classes. The class must supply the required abstract
+methods. The remaining mixin methods come from inheritance and can be
+overridden if desired. Other methods may be added as needed:
+
+.. testcode::
+
+ class C(Sequence): # Direct inheritance
+ def __init__(self): ... # Extra method not required by the ABC
+ def __getitem__(self, index): ... # Required abstract method
+ def __len__(self): ... # Required abstract method
+ def count(self, value): ... # Optionally override a mixin method
+
+.. doctest::
+
+ >>> issubclass(C, Sequence)
+ True
+ >>> isinstance(C(), Sequence)
+ True
+
+2) Existing classes and built-in classes can be registered as "virtual
+subclasses" of the ABCs. Those classes should define the full API
+including all of the abstract methods and all of the mixin methods.
+This lets users rely on :func:`issubclass` or :func:`isinstance` tests
+to determine whether the full interface is supported. The exception to
+this rule is for methods that are automatically inferred from the rest
+of the API:
+
+.. testcode::
+
+ class D: # No inheritance
+ def __init__(self): ... # Extra method not required by the ABC
+ def __getitem__(self, index): ... # Abstract method
+ def __len__(self): ... # Abstract method
+ def count(self, value): ... # Mixin method
+ def index(self, value): ... # Mixin method
+
+ Sequence.register(D) # Register instead of inherit
+
+.. doctest::
+
+ >>> issubclass(D, Sequence)
+ True
+ >>> isinstance(D(), Sequence)
+ True
+
+In this example, class :class:`D` does not need to define
+``__contains__``, ``__iter__``, and ``__reversed__`` because the
+:ref:`in-operator `, the :term:`iteration `
+logic, and the :func:`reversed` function automatically fall back to
+using ``__getitem__`` and ``__len__``.
+
+3) Some simple interfaces are directly recognizable by the presence of
+the required methods (unless those methods have been set to
+:const:`None`):
+
+.. testcode::
+
+ class E:
+ def __iter__(self): ...
+ def __next__(next): ...
+
+.. doctest::
+
+ >>> issubclass(E, Iterable)
+ True
+ >>> isinstance(E(), Iterable)
+ True
+
+Complex interfaces do not support this last technique because an
+interface is more than just the presence of method names. Interfaces
+specify semantics and relationships between methods that cannot be
+inferred solely from the presence of specific method names. For
+example, knowing that a class supplies ``__getitem__``, ``__len__``, and
+``__iter__`` is insufficient for distinguishing a :class:`Sequence` from
+a :class:`Mapping`.
+
+.. versionadded:: 3.9
+ These abstract classes now support ``[]``. See :ref:`types-genericalias`
+ and :pep:`585`.
.. _collections-abstract-base-classes:
@@ -34,67 +117,86 @@ The collections module offers the following :term:`ABCs `:
.. tabularcolumns:: |l|L|L|L|
-========================== ====================== ======================= ====================================================
-ABC Inherits from Abstract Methods Mixin Methods
-========================== ====================== ======================= ====================================================
-:class:`Container` ``__contains__``
-:class:`Hashable` ``__hash__``
-:class:`Iterable` ``__iter__``
-:class:`Iterator` :class:`Iterable` ``__next__`` ``__iter__``
-:class:`Reversible` :class:`Iterable` ``__reversed__``
-:class:`Generator` :class:`Iterator` ``send``, ``throw`` ``close``, ``__iter__``, ``__next__``
-:class:`Sized` ``__len__``
-:class:`Callable` ``__call__``
-:class:`Collection` :class:`Sized`, ``__contains__``,
- :class:`Iterable`, ``__iter__``,
- :class:`Container` ``__len__``
-
-:class:`Sequence` :class:`Reversible`, ``__getitem__``, ``__contains__``, ``__iter__``, ``__reversed__``,
- :class:`Collection` ``__len__`` ``index``, and ``count``
-
-:class:`MutableSequence` :class:`Sequence` ``__getitem__``, Inherited :class:`Sequence` methods and
- ``__setitem__``, ``append``, ``reverse``, ``extend``, ``pop``,
- ``__delitem__``, ``remove``, and ``__iadd__``
- ``__len__``,
- ``insert``
-
-:class:`ByteString` :class:`Sequence` ``__getitem__``, Inherited :class:`Sequence` methods
- ``__len__``
-
-:class:`Set` :class:`Collection` ``__contains__``, ``__le__``, ``__lt__``, ``__eq__``, ``__ne__``,
- ``__iter__``, ``__gt__``, ``__ge__``, ``__and__``, ``__or__``,
- ``__len__`` ``__sub__``, ``__xor__``, and ``isdisjoint``
-
-:class:`MutableSet` :class:`Set` ``__contains__``, Inherited :class:`Set` methods and
- ``__iter__``, ``clear``, ``pop``, ``remove``, ``__ior__``,
- ``__len__``, ``__iand__``, ``__ixor__``, and ``__isub__``
- ``add``,
- ``discard``
-
-:class:`Mapping` :class:`Collection` ``__getitem__``, ``__contains__``, ``keys``, ``items``, ``values``,
- ``__iter__``, ``get``, ``__eq__``, and ``__ne__``
- ``__len__``
-
-:class:`MutableMapping` :class:`Mapping` ``__getitem__``, Inherited :class:`Mapping` methods and
- ``__setitem__``, ``pop``, ``popitem``, ``clear``, ``update``,
- ``__delitem__``, and ``setdefault``
- ``__iter__``,
- ``__len__``
-
-
-:class:`MappingView` :class:`Sized` ``__len__``
-:class:`ItemsView` :class:`MappingView`, ``__contains__``,
- :class:`Set` ``__iter__``
-:class:`KeysView` :class:`MappingView`, ``__contains__``,
- :class:`Set` ``__iter__``
-:class:`ValuesView` :class:`MappingView`, ``__contains__``, ``__iter__``
- :class:`Collection`
-:class:`Awaitable` ``__await__``
-:class:`Coroutine` :class:`Awaitable` ``send``, ``throw`` ``close``
-:class:`AsyncIterable` ``__aiter__``
-:class:`AsyncIterator` :class:`AsyncIterable` ``__anext__`` ``__aiter__``
-:class:`AsyncGenerator` :class:`AsyncIterator` ``asend``, ``athrow`` ``aclose``, ``__aiter__``, ``__anext__``
-========================== ====================== ======================= ====================================================
+============================== ====================== ======================= ====================================================
+ABC Inherits from Abstract Methods Mixin Methods
+============================== ====================== ======================= ====================================================
+:class:`Container` [1]_ ``__contains__``
+:class:`Hashable` [1]_ ``__hash__``
+:class:`Iterable` [1]_ [2]_ ``__iter__``
+:class:`Iterator` [1]_ :class:`Iterable` ``__next__`` ``__iter__``
+:class:`Reversible` [1]_ :class:`Iterable` ``__reversed__``
+:class:`Generator` [1]_ :class:`Iterator` ``send``, ``throw`` ``close``, ``__iter__``, ``__next__``
+:class:`Sized` [1]_ ``__len__``
+:class:`Callable` [1]_ ``__call__``
+:class:`Collection` [1]_ :class:`Sized`, ``__contains__``,
+ :class:`Iterable`, ``__iter__``,
+ :class:`Container` ``__len__``
+
+:class:`Sequence` :class:`Reversible`, ``__getitem__``, ``__contains__``, ``__iter__``, ``__reversed__``,
+ :class:`Collection` ``__len__`` ``index``, and ``count``
+
+:class:`MutableSequence` :class:`Sequence` ``__getitem__``, Inherited :class:`Sequence` methods and
+ ``__setitem__``, ``append``, ``reverse``, ``extend``, ``pop``,
+ ``__delitem__``, ``remove``, and ``__iadd__``
+ ``__len__``,
+ ``insert``
+
+:class:`ByteString` :class:`Sequence` ``__getitem__``, Inherited :class:`Sequence` methods
+ ``__len__``
+
+:class:`Set` :class:`Collection` ``__contains__``, ``__le__``, ``__lt__``, ``__eq__``, ``__ne__``,
+ ``__iter__``, ``__gt__``, ``__ge__``, ``__and__``, ``__or__``,
+ ``__len__`` ``__sub__``, ``__xor__``, and ``isdisjoint``
+
+:class:`MutableSet` :class:`Set` ``__contains__``, Inherited :class:`Set` methods and
+ ``__iter__``, ``clear``, ``pop``, ``remove``, ``__ior__``,
+ ``__len__``, ``__iand__``, ``__ixor__``, and ``__isub__``
+ ``add``,
+ ``discard``
+
+:class:`Mapping` :class:`Collection` ``__getitem__``, ``__contains__``, ``keys``, ``items``, ``values``,
+ ``__iter__``, ``get``, ``__eq__``, and ``__ne__``
+ ``__len__``
+
+:class:`MutableMapping` :class:`Mapping` ``__getitem__``, Inherited :class:`Mapping` methods and
+ ``__setitem__``, ``pop``, ``popitem``, ``clear``, ``update``,
+ ``__delitem__``, and ``setdefault``
+ ``__iter__``,
+ ``__len__``
+
+
+:class:`MappingView` :class:`Sized` ``__len__``
+:class:`ItemsView` :class:`MappingView`, ``__contains__``,
+ :class:`Set` ``__iter__``
+:class:`KeysView` :class:`MappingView`, ``__contains__``,
+ :class:`Set` ``__iter__``
+:class:`ValuesView` :class:`MappingView`, ``__contains__``, ``__iter__``
+ :class:`Collection`
+:class:`Awaitable` [1]_ ``__await__``
+:class:`Coroutine` [1]_ :class:`Awaitable` ``send``, ``throw`` ``close``
+:class:`AsyncIterable` [1]_ ``__aiter__``
+:class:`AsyncIterator` [1]_ :class:`AsyncIterable` ``__anext__`` ``__aiter__``
+:class:`AsyncGenerator` [1]_ :class:`AsyncIterator` ``asend``, ``athrow`` ``aclose``, ``__aiter__``, ``__anext__``
+============================== ====================== ======================= ====================================================
+
+
+.. rubric:: Footnotes
+
+.. [1] These ABCs override :meth:`object.__subclasshook__` to support
+ testing an interface by verifying the required methods are present
+ and have not been set to :const:`None`. This only works for simple
+ interfaces. More complex interfaces require registration or direct
+ subclassing.
+
+.. [2] Checking ``isinstance(obj, Iterable)`` detects classes that are
+ registered as :class:`Iterable` or that have an :meth:`__iter__`
+ method, but it does not detect classes that iterate with the
+ :meth:`__getitem__` method. The only reliable way to determine
+ whether an object is :term:`iterable` is to call ``iter(obj)``.
+
+
+Collections Abstract Base Classes -- Detailed Descriptions
+----------------------------------------------------------
.. class:: Container
@@ -244,8 +346,10 @@ ABC Inherits from Abstract Methods Mixin
.. versionadded:: 3.6
+Examples and Recipes
+--------------------
-These ABCs allow us to ask classes or instances if they provide
+ABCs allow us to ask classes or instances if they provide
particular functionality, for example::
size = None
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index 94166ec6c754a7..67b64ddda7a2ca 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -271,12 +271,12 @@ For example::
.. versionadded:: 3.1
.. versionchanged:: 3.7 As a :class:`dict` subclass, :class:`Counter`
- Inherited the capability to remember insertion order. Math operations
+ inherited the capability to remember insertion order. Math operations
on *Counter* objects also preserve order. Results are ordered
according to when an element is first encountered in the left operand
and then by the order encountered in the right operand.
- Counter objects support three methods beyond those available for all
+ Counter objects support additional methods beyond those available for all
dictionaries:
.. method:: elements()
@@ -343,7 +343,7 @@ All of those tests treat missing elements as having zero counts so that
``Counter(a=1) == Counter(a=1, b=0)`` returns true.
.. versionadded:: 3.10
- Rich comparison operations we were added
+ Rich comparison operations were added.
.. versionchanged:: 3.10
In equality tests, missing elements are treated as having zero counts.
@@ -366,19 +366,26 @@ Several mathematical operations are provided for combining :class:`Counter`
objects to produce multisets (counters that have counts greater than zero).
Addition and subtraction combine counters by adding or subtracting the counts
of corresponding elements. Intersection and union return the minimum and
-maximum of corresponding counts. Each operation can accept inputs with signed
+maximum of corresponding counts. Equality and inclusion compare
+corresponding counts. Each operation can accept inputs with signed
counts, but the output will exclude results with counts of zero or less.
+.. doctest::
+
>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d # add two counters together: c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d # subtract (keeping only positive counts)
Counter({'a': 2})
- >>> c & d # intersection: min(c[x], d[x]) # doctest: +SKIP
+ >>> c & d # intersection: min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d # union: max(c[x], d[x])
Counter({'a': 3, 'b': 2})
+ >>> c == d # equality: c[x] == d[x]
+ False
+ >>> c <= d # inclusion: c[x] <= d[x]
+ False
Unary addition and subtraction are shortcuts for adding an empty counter
or subtracting from an empty counter.
@@ -707,9 +714,9 @@ stack manipulations such as ``dup``, ``drop``, ``swap``, ``over``, ``pick``,
:class:`defaultdict` objects
----------------------------
-.. class:: defaultdict([default_factory[, ...]])
+.. class:: defaultdict(default_factory=None, /, [...])
- Returns a new dictionary-like object. :class:`defaultdict` is a subclass of the
+ Return a new dictionary-like object. :class:`defaultdict` is a subclass of the
built-in :class:`dict` class. It overrides one method and adds one writable
instance variable. The remaining functionality is the same as for the
:class:`dict` class and is not documented here.
@@ -1085,18 +1092,35 @@ Some differences from :class:`dict` still remain:
Space efficiency, iteration speed, and the performance of update
operations were secondary.
-* Algorithmically, :class:`OrderedDict` can handle frequent reordering
- operations better than :class:`dict`. This makes it suitable for tracking
- recent accesses (for example in an `LRU cache
- `_).
+* The :class:`OrderedDict` algorithm can handle frequent reordering operations
+ better than :class:`dict`. As shown in the recipes below, this makes it
+ suitable for implementing various kinds of LRU caches.
* The equality operation for :class:`OrderedDict` checks for matching order.
+ A regular :class:`dict` can emulate the order sensitive equality test with
+ ``p == q and all(k1 == k2 for k1, k2 in zip(p, q))``.
+
* The :meth:`popitem` method of :class:`OrderedDict` has a different
signature. It accepts an optional argument to specify which item is popped.
-* :class:`OrderedDict` has a :meth:`move_to_end` method to
- efficiently reposition an element to an endpoint.
+ A regular :class:`dict` can emulate OrderedDict's ``od.popitem(last=True)``
+ with ``d.popitem()`` which is guaranteed to pop the rightmost (last) item.
+
+ A regular :class:`dict` can emulate OrderedDict's ``od.popitem(last=False)``
+ with ``(k := next(iter(d)), d.pop(k))`` which will return and remove the
+ leftmost (first) item if it exists.
+
+* :class:`OrderedDict` has a :meth:`move_to_end` method to efficiently
+ reposition an element to an endpoint.
+
+ A regular :class:`dict` can emulate OrderedDict's ``od.move_to_end(k,
+ last=True)`` with ``d[k] = d.pop(k)`` which will move the key and its
+ associated value to the rightmost (last) position.
+
+ A regular :class:`dict` does not have an efficient equivalent for
+ OrderedDict's ``od.move_to_end(k, last=False)`` which moves the key
+ and its associated value to the leftmost (first) position.
* Until Python 3.8, :class:`dict` lacked a :meth:`__reversed__` method.
@@ -1120,14 +1144,16 @@ Some differences from :class:`dict` still remain:
Move an existing *key* to either end of an ordered dictionary. The item
is moved to the right end if *last* is true (the default) or to the
beginning if *last* is false. Raises :exc:`KeyError` if the *key* does
- not exist::
+ not exist:
+
+ .. doctest::
>>> d = OrderedDict.fromkeys('abcde')
>>> d.move_to_end('b')
- >>> ''.join(d.keys())
+ >>> ''.join(d)
'acdeb'
>>> d.move_to_end('b', last=False)
- >>> ''.join(d.keys())
+ >>> ''.join(d)
'bacde'
.. versionadded:: 3.2
@@ -1171,28 +1197,101 @@ original insertion position is changed and moved to the end::
self.move_to_end(key)
An :class:`OrderedDict` would also be useful for implementing
-variants of :func:`functools.lru_cache`::
+variants of :func:`functools.lru_cache`:
- class LRU(OrderedDict):
- 'Limit size, evicting the least recently looked-up key when full'
+.. testcode::
- def __init__(self, maxsize=128, /, *args, **kwds):
- self.maxsize = maxsize
- super().__init__(*args, **kwds)
+ from time import time
- def __getitem__(self, key):
- value = super().__getitem__(key)
- self.move_to_end(key)
- return value
+ class TimeBoundedLRU:
+ "LRU Cache that invalidates and refreshes old entries."
- def __setitem__(self, key, value):
- if key in self:
- self.move_to_end(key)
- super().__setitem__(key, value)
- if len(self) > self.maxsize:
- oldest = next(iter(self))
- del self[oldest]
+ def __init__(self, func, maxsize=128, maxage=30):
+ self.cache = OrderedDict() # { args : (timestamp, result)}
+ self.func = func
+ self.maxsize = maxsize
+ self.maxage = maxage
+
+ def __call__(self, *args):
+ if args in self.cache:
+ self.cache.move_to_end(args)
+ timestamp, result = self.cache[args]
+ if time() - timestamp <= self.maxage:
+ return result
+ result = self.func(*args)
+ self.cache[args] = time(), result
+ if len(self.cache) > self.maxsize:
+ self.cache.popitem(0)
+ return result
+
+
+.. testcode::
+
+ class MultiHitLRUCache:
+ """ LRU cache that defers caching a result until
+ it has been requested multiple times.
+
+ To avoid flushing the LRU cache with one-time requests,
+ we don't cache until a request has been made more than once.
+
+ """
+
+ def __init__(self, func, maxsize=128, maxrequests=4096, cache_after=1):
+ self.requests = OrderedDict() # { uncached_key : request_count }
+ self.cache = OrderedDict() # { cached_key : function_result }
+ self.func = func
+ self.maxrequests = maxrequests # max number of uncached requests
+ self.maxsize = maxsize # max number of stored return values
+ self.cache_after = cache_after
+
+ def __call__(self, *args):
+ if args in self.cache:
+ self.cache.move_to_end(args)
+ return self.cache[args]
+ result = self.func(*args)
+ self.requests[args] = self.requests.get(args, 0) + 1
+ if self.requests[args] <= self.cache_after:
+ self.requests.move_to_end(args)
+ if len(self.requests) > self.maxrequests:
+ self.requests.popitem(0)
+ else:
+ self.requests.pop(args, None)
+ self.cache[args] = result
+ if len(self.cache) > self.maxsize:
+ self.cache.popitem(0)
+ return result
+.. doctest::
+ :hide:
+
+ >>> def square(x):
+ ... return x * x
+ ...
+ >>> f = MultiHitLRUCache(square, maxsize=4, maxrequests=6)
+ >>> list(map(f, range(10))) # First requests, don't cache
+ [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
+ >>> f(4) # Cache the second request
+ 16
+ >>> f(6) # Cache the second request
+ 36
+ >>> f(2) # The first request aged out, so don't cache
+ 4
+ >>> f(6) # Cache hit
+ 36
+ >>> f(4) # Cache hit and move to front
+ 16
+ >>> list(f.cache.values())
+ [36, 16]
+ >>> set(f.requests).isdisjoint(f.cache)
+ True
+ >>> list(map(f, [9, 8, 7])) # Cache these second requests
+ [81, 64, 49]
+ >>> list(map(f, [7, 9])) # Cache hits
+ [49, 81]
+ >>> list(f.cache.values())
+ [16, 64, 49, 81]
+ >>> set(f.requests).isdisjoint(f.cache)
+ True
:class:`UserDict` objects
-------------------------
@@ -1209,7 +1308,7 @@ attribute.
regular dictionary, which is accessible via the :attr:`data` attribute of
:class:`UserDict` instances. If *initialdata* is provided, :attr:`data` is
initialized with its contents; note that a reference to *initialdata* will not
- be kept, allowing it be used for other purposes.
+ be kept, allowing it to be used for other purposes.
In addition to supporting the methods and operations of mappings,
:class:`UserDict` instances provide the following attribute:
diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst
index 5c6e68f9304753..de34664acb84ab 100644
--- a/Doc/library/compileall.rst
+++ b/Doc/library/compileall.rst
@@ -166,9 +166,10 @@ Public functions
If *force* is true, modules are re-compiled even if the timestamps are up to
date.
- If *rx* is given, its search method is called on the complete path to each
+ If *rx* is given, its ``search`` method is called on the complete path to each
file considered for compilation, and if it returns a true value, the file
- is skipped.
+ is skipped. This can be used to exclude files matching a regular expression,
+ given as a :ref:`re.Pattern ` object.
If *quiet* is ``False`` or ``0`` (the default), the filenames and other
information are printed to standard out. Set to ``1``, only errors are
@@ -242,9 +243,10 @@ Public functions
cases where the source file does not exist at the time the byte-code file is
executed.
- If *rx* is given, its search method is passed the full path name to the
+ If *rx* is given, its ``search`` method is passed the full path name to the
file being compiled, and if it returns a true value, the file is not
- compiled and ``True`` is returned.
+ compiled and ``True`` is returned. This can be used to exclude files matching
+ a regular expression, given as a :ref:`re.Pattern ` object.
If *quiet* is ``False`` or ``0`` (the default), the filenames and other
information are printed to standard out. Set to ``1``, only errors are
diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst
index d57f8ce23d12c4..70a17a23119c12 100644
--- a/Doc/library/concurrent.futures.rst
+++ b/Doc/library/concurrent.futures.rst
@@ -30,7 +30,7 @@ Executor Objects
.. method:: submit(fn, /, *args, **kwargs)
- Schedules the callable, *fn*, to be executed as ``fn(*args **kwargs)``
+ Schedules the callable, *fn*, to be executed as ``fn(*args, **kwargs)``
and returns a :class:`Future` object representing the execution of the
callable. ::
@@ -350,7 +350,7 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable.
If the future is cancelled before completing then :exc:`.CancelledError`
will be raised.
- If the call raised, this method will raise the same exception.
+ If the call raised an exception, this method will raise the same exception.
.. method:: exception(timeout=None)
@@ -435,7 +435,8 @@ Module Functions
.. function:: wait(fs, timeout=None, return_when=ALL_COMPLETED)
Wait for the :class:`Future` instances (possibly created by different
- :class:`Executor` instances) given by *fs* to complete. Returns a named
+ :class:`Executor` instances) given by *fs* to complete. Duplicate futures
+ given to *fs* are removed and will be returned only once. Returns a named
2-tuple of sets. The first set, named ``done``, contains the futures that
completed (finished or cancelled futures) before the wait completed. The
second set, named ``not_done``, contains the futures that did not complete
diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst
index 646e8a317f52c3..72aa20d73d8bd3 100644
--- a/Doc/library/configparser.rst
+++ b/Doc/library/configparser.rst
@@ -46,6 +46,11 @@ can be customized by end users easily.
import configparser
+.. testcleanup::
+
+ import os
+ os.remove("example.ini")
+
Quick Start
-----------
@@ -256,11 +261,15 @@ A configuration file consists of sections, each led by a ``[section]`` header,
followed by key/value entries separated by a specific string (``=`` or ``:`` by
default [1]_). By default, section names are case sensitive but keys are not
[1]_. Leading and trailing whitespace is removed from keys and values.
-Values can be omitted, in which case the key/value delimiter may also be left
+Values can be omitted if the parser is configured to allow it [1]_,
+in which case the key/value delimiter may also be left
out. Values can also span multiple lines, as long as they are indented deeper
than the first line of the value. Depending on the parser's mode, blank lines
may be treated as parts of multiline values or ignored.
+By default, a valid section name can be any string that does not contain '\\n' or ']'.
+To change this, see :attr:`ConfigParser.SECTCRE`.
+
Configuration files may include comments, prefixed by specific
characters (``#`` and ``;`` by default [1]_). Comments may appear on
their own on an otherwise empty line, possibly indented. [1]_
@@ -338,7 +347,8 @@ from ``get()`` calls.
my_pictures: %(my_dir)s/Pictures
[Escape]
- gain: 80%% # use a %% to escape the % sign (% is the only character that needs to be escaped)
+ # use a %% to escape the % sign (% is the only character that needs to be escaped):
+ gain: 80%%
In the example above, :class:`ConfigParser` with *interpolation* set to
``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of
@@ -373,7 +383,8 @@ from ``get()`` calls.
my_pictures: ${my_dir}/Pictures
[Escape]
- cost: $$80 # use a $$ to escape the $ sign ($ is the only character that needs to be escaped)
+ # use a $$ to escape the $ sign ($ is the only character that needs to be escaped):
+ cost: $$80
Values from other sections can be fetched as well:
@@ -1153,6 +1164,13 @@ ConfigParser Objects
*space_around_delimiters* is true, delimiters between
keys and values are surrounded by spaces.
+ .. note::
+
+ Comments in the original configuration file are not preserved when
+ writing the configuration back.
+ What is considered a comment, depends on the given values for
+ *comment_prefix* and *inline_comment_prefix*.
+
.. method:: remove_option(section, option)
diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst
index b92f703509fcac..7c0b8314079683 100644
--- a/Doc/library/contextlib.rst
+++ b/Doc/library/contextlib.rst
@@ -130,7 +130,9 @@ Functions and classes provided:
either as decorators or with :keyword:`async with` statements::
import time
+ from contextlib import asynccontextmanager
+ @asynccontextmanager
async def timeit():
now = time.monotonic()
try:
@@ -171,7 +173,7 @@ Functions and classes provided:
from contextlib import closing
from urllib.request import urlopen
- with closing(urlopen('http://www.python.org')) as page:
+ with closing(urlopen('https://www.python.org')) as page:
for line in page:
print(line)
@@ -179,7 +181,7 @@ Functions and classes provided:
``page.close()`` will be called when the :keyword:`with` block is exited.
-.. class:: aclosing(thing)
+.. function:: aclosing(thing)
Return an async context manager that calls the ``aclose()`` method of *thing*
upon completion of the block. This is basically equivalent to::
@@ -267,8 +269,9 @@ Functions and classes provided:
.. function:: suppress(*exceptions)
Return a context manager that suppresses any of the specified exceptions
- if they occur in the body of a with statement and then resumes execution
- with the first statement following the end of the with statement.
+ if they occur in the body of a :keyword:`!with` statement and then
+ resumes execution with the first statement following the end of the
+ :keyword:`!with` statement.
As with any other mechanism that completely suppresses exceptions, this
context manager should be used only to cover very specific errors where
@@ -312,10 +315,11 @@ Functions and classes provided:
For example, the output of :func:`help` normally is sent to *sys.stdout*.
You can capture that output in a string by redirecting the output to an
- :class:`io.StringIO` object::
+ :class:`io.StringIO` object. The replacement stream is returned from the
+ ``__enter__`` method and so is available as the target of the
+ :keyword:`with` statement::
- f = io.StringIO()
- with redirect_stdout(f):
+ with redirect_stdout(io.StringIO()) as f:
help(pow)
s = f.getvalue()
@@ -481,6 +485,9 @@ Functions and classes provided:
# the with statement, even if attempts to open files later
# in the list raise an exception
+ The :meth:`__enter__` method returns the :class:`ExitStack` instance, and
+ performs no additional operations.
+
Each instance maintains a stack of registered callbacks that are called in
reverse order when the instance is closed (either explicitly or implicitly
at the end of a :keyword:`with` statement). Note that callbacks are *not*
@@ -578,7 +585,7 @@ Functions and classes provided:
The :meth:`close` method is not implemented, :meth:`aclose` must be used
instead.
- .. method:: enter_async_context(cm)
+ .. coroutinemethod:: enter_async_context(cm)
Similar to :meth:`enter_context` but expects an asynchronous context
manager.
@@ -592,7 +599,7 @@ Functions and classes provided:
Similar to :meth:`callback` but expects a coroutine function.
- .. method:: aclose()
+ .. coroutinemethod:: aclose()
Similar to :meth:`close` but properly handles awaitables.
diff --git a/Doc/library/contextvars.rst b/Doc/library/contextvars.rst
index 14ac47f4c9eb16..be1dd0c9eb57e8 100644
--- a/Doc/library/contextvars.rst
+++ b/Doc/library/contextvars.rst
@@ -94,7 +94,7 @@ Context Variables
# var.get() would raise a LookupError.
-.. class:: contextvars.Token
+.. class:: Token
*Token* objects are returned by the :meth:`ContextVar.set` method.
They can be passed to the :meth:`ContextVar.reset` method to revert
diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst
index 01ebf198d7c501..a8bc2fa55ea8c3 100644
--- a/Doc/library/copy.rst
+++ b/Doc/library/copy.rst
@@ -60,7 +60,7 @@ The :func:`deepcopy` function avoids these problems by:
components copied.
This module does not copy types like module, method, stack trace, stack frame,
-file, socket, window, array, or any similar types. It does "copy" functions and
+file, socket, window, or any similar types. It does "copy" functions and
classes (shallow and deeply), by returning the original object unchanged; this
is compatible with the way these are treated by the :mod:`pickle` module.
diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst
index 43920210095951..dc35965be3e40d 100644
--- a/Doc/library/copyreg.rst
+++ b/Doc/library/copyreg.rst
@@ -33,8 +33,8 @@ Such constructors may be factory functions or class instances.
The optional *constructor* parameter, if provided, is a callable object which
can be used to reconstruct the object when called with the tuple of arguments
- returned by *function* at pickling time. :exc:`TypeError` will be raised if
- *object* is a class or *constructor* is not callable.
+ returned by *function* at pickling time. A :exc:`TypeError` is raised if the
+ *constructor* is not callable.
See the :mod:`pickle` module for more details on the interface
expected of *function* and *constructor*. Note that the
diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst
index d25c626a175854..e795f10f50eec3 100644
--- a/Doc/library/crypt.rst
+++ b/Doc/library/crypt.rst
@@ -4,6 +4,7 @@
.. module:: crypt
:platform: Unix
:synopsis: The crypt() function used to check Unix passwords.
+ :deprecated:
.. moduleauthor:: Steven D. Majewski
.. sectionauthor:: Steven D. Majewski
@@ -15,6 +16,11 @@
single: crypt(3)
pair: cipher; DES
+.. deprecated:: 3.11
+ The :mod:`crypt` module is deprecated
+ (see :pep:`PEP 594 <594#crypt>` for details and alternatives).
+ The :mod:`hashlib` module is a potential replacement for certain use cases.
+
--------------
This module implements an interface to the :manpage:`crypt(3)` routine, which is
@@ -92,8 +98,7 @@ The :mod:`crypt` module defines the following functions:
:func:`mksalt`, one of the ``crypt.METHOD_*`` values (though not all
may be available on all platforms), or a full encrypted password
including salt, as returned by this function. If *salt* is not
- provided, the strongest method will be used (as returned by
- :func:`methods`).
+ provided, the strongest method available in :attr:`methods` will be used.
Checking a password is usually done by passing the plain-text password
as *word* and the full results of a previous :func:`crypt` call,
@@ -121,8 +126,8 @@ The :mod:`crypt` module defines the following functions:
.. function:: mksalt(method=None, *, rounds=None)
Return a randomly generated salt of the specified method. If no
- *method* is given, the strongest method available as returned by
- :func:`methods` is used.
+ *method* is given, the strongest method available in :attr:`methods` is
+ used.
The return value is a string suitable for passing as the *salt* argument
to :func:`crypt`.
diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst
index 7a72c26d5badeb..899ce0225ce7f3 100644
--- a/Doc/library/csv.rst
+++ b/Doc/library/csv.rst
@@ -94,8 +94,8 @@ The :mod:`csv` module defines the following functions:
:class:`Dialect` class or one of the strings returned by the
:func:`list_dialects` function. The other optional *fmtparams* keyword arguments
can be given to override individual formatting parameters in the current
- dialect. For full details about the dialect and formatting parameters, see
- section :ref:`csv-fmt-params`. To make it
+ dialect. For full details about dialects and formatting parameters, see
+ the :ref:`csv-fmt-params` section. To make it
as easy as possible to interface with modules which implement the DB API, the
value :const:`None` is written as the empty string. While this isn't a
reversible transformation, it makes it easier to dump SQL NULL data values to
@@ -117,7 +117,7 @@ The :mod:`csv` module defines the following functions:
Associate *dialect* with *name*. *name* must be a string. The
dialect can be specified either by passing a sub-class of :class:`Dialect`, or
by *fmtparams* keyword arguments, or both, with keyword arguments overriding
- parameters of the dialect. For full details about the dialect and formatting
+ parameters of the dialect. For full details about dialects and formatting
parameters, see section :ref:`csv-fmt-params`.
@@ -225,9 +225,21 @@ The :mod:`csv` module defines the following classes:
.. class:: Dialect
- The :class:`Dialect` class is a container class relied on primarily for its
- attributes, which are used to define the parameters for a specific
- :class:`reader` or :class:`writer` instance.
+ The :class:`Dialect` class is a container class whose attributes contain
+ information for how to handle doublequotes, whitespace, delimiters, etc.
+ Due to the lack of a strict CSV specification, different applications
+ produce subtly different CSV data. :class:`Dialect` instances define how
+ :class:`reader` and :class:`writer` instances behave.
+
+ All available :class:`Dialect` names are returned by :func:`list_dialects`,
+ and they can be registered with specific :class:`reader` and :class:`writer`
+ classes through their initializer (``__init__``) functions like this::
+
+ import csv
+
+ with open('students.csv', 'w', newline='') as csvfile:
+ writer = csv.writer(csvfile, dialect='unix')
+ ^^^^^^^^^^^^^^
.. class:: excel()
@@ -269,6 +281,20 @@ The :mod:`csv` module defines the following classes:
Analyze the sample text (presumed to be in CSV format) and return
:const:`True` if the first row appears to be a series of column headers.
+ Inspecting each column, one of two key criteria will be considered to
+ estimate if the sample contains a header:
+
+ - the second through n-th rows contain numeric values
+ - the second through n-th rows contain strings where at least one value's
+ length differs from that of the putative header of that column.
+
+ Twenty rows after the first row are sampled; if more than half of columns +
+ rows meet the criteria, :const:`True` is returned.
+
+ .. note::
+
+ This method is a rough heuristic and may produce both false positives and
+ negatives.
An example for :class:`Sniffer` use::
@@ -405,8 +431,8 @@ Reader objects (:class:`DictReader` instances and objects returned by the
Return the next row of the reader's iterable object as a list (if the object
was returned from :func:`reader`) or a dict (if it is a :class:`DictReader`
- instance), parsed according to the current dialect. Usually you should call
- this as ``next(reader)``.
+ instance), parsed according to the current :class:`Dialect`. Usually you
+ should call this as ``next(reader)``.
Reader objects have the following public attributes:
@@ -446,9 +472,9 @@ read CSV files (assuming they support complex numbers at all).
.. method:: csvwriter.writerow(row)
- Write the *row* parameter to the writer's file object, formatted according to
- the current dialect. Return the return value of the call to the *write* method
- of the underlying file object.
+ Write the *row* parameter to the writer's file object, formatted according
+ to the current :class:`Dialect`. Return the return value of the call to the
+ *write* method of the underlying file object.
.. versionchanged:: 3.5
Added support of arbitrary iterables.
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index fd6422cc8c06c5..19ce19b1d70d1d 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -20,7 +20,7 @@ ctypes tutorial
Note: The code samples in this tutorial use :mod:`doctest` to make sure that
they actually work. Since some code samples behave differently under Linux,
-Windows, or Mac OS X, they contain doctest directives in comments.
+Windows, or macOS, they contain doctest directives in comments.
Note: Some code samples reference the ctypes :class:`c_int` type. On platforms
where ``sizeof(long) == sizeof(int)`` it is an alias to :class:`c_long`.
@@ -80,7 +80,7 @@ the library by creating an instance of CDLL by calling the constructor::
>>>
-.. XXX Add section for Mac OS X.
+.. XXX Add section for macOS.
.. _ctypes-accessing-functions-from-loaded-dlls:
@@ -1288,7 +1288,7 @@ Here are some examples::
'libbz2.so.1.0'
>>>
-On OS X, :func:`find_library` tries several predefined naming schemes and paths
+On macOS, :func:`find_library` tries several predefined naming schemes and paths
to locate the library, and returns a full pathname if successful::
>>> from ctypes.util import find_library
@@ -1320,7 +1320,7 @@ There are several ways to load shared libraries into the Python process. One
way is to instantiate one of the following classes:
-.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0)
+.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
Instances of this class represent loaded shared libraries. Functions in these
libraries use the standard C calling convention, and are assumed to return
@@ -1342,7 +1342,7 @@ way is to instantiate one of the following classes:
-- A tool to find DLL dependents.
-.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0)
+.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
Windows only: Instances of this class represent loaded shared libraries,
functions in these libraries use the ``stdcall`` calling convention, and are
@@ -1355,16 +1355,12 @@ way is to instantiate one of the following classes:
:exc:`WindowsError` used to be raised.
-.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0)
+.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
Windows only: Instances of this class represent loaded shared libraries,
functions in these libraries use the ``stdcall`` calling convention, and are
assumed to return :c:type:`int` by default.
- On Windows CE only the standard calling convention is used, for convenience the
- :class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this
- platform.
-
The Python :term:`global interpreter lock` is released before calling any
function exported by these libraries, and reacquired afterwards.
@@ -1665,8 +1661,7 @@ See :ref:`ctypes-callback-functions` for examples.
.. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)
Windows only: The returned function prototype creates functions that use the
- ``stdcall`` calling convention, except on Windows CE where
- :func:`WINFUNCTYPE` is the same as :func:`CFUNCTYPE`. The function will
+ ``stdcall`` calling convention. The function will
release the GIL during the call. *use_errno* and *use_last_error* have the
same meaning as above.
@@ -2513,7 +2508,7 @@ Arrays and pointers
Abstract base class for arrays.
The recommended way to create concrete array types is by multiplying any
- :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass
+ :mod:`ctypes` data type with a non-negative integer. Alternatively, you can subclass
this type and define :attr:`_length_` and :attr:`_type_` class variables.
Array elements can be read and written using standard
subscript and slice accesses; for slice reads, the resulting object is
diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst
index 64540b3e963b52..1fe5bda3b9415d 100644
--- a/Doc/library/dataclasses.rst
+++ b/Doc/library/dataclasses.rst
@@ -17,7 +17,7 @@ adding generated :term:`special method`\s such as :meth:`__init__` and
in :pep:`557`.
The member variables to use in these generated methods are defined
-using :pep:`526` type annotations. For example this code::
+using :pep:`526` type annotations. For example, this code::
from dataclasses import dataclass
@@ -31,7 +31,7 @@ using :pep:`526` type annotations. For example this code::
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
-Will add, among other things, a :meth:`__init__` that looks like::
+will add, among other things, a :meth:`__init__` that looks like::
def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0):
self.name = name
@@ -52,7 +52,7 @@ Module contents
:term:`special method`\s to classes, as described below.
The :func:`dataclass` decorator examines the class to find
- ``field``\s. A ``field`` is defined as class variable that has a
+ ``field``\s. A ``field`` is defined as a class variable that has a
:term:`type annotation `. With two
exceptions described below, nothing in :func:`dataclass`
examines the type specified in the variable annotation.
@@ -62,8 +62,8 @@ Module contents
The :func:`dataclass` decorator will add various "dunder" methods to
the class, described below. If any of the added methods already
- exist on the class, the behavior depends on the parameter, as documented
- below. The decorator returns the same class that is called on; no new
+ exist in the class, the behavior depends on the parameter, as documented
+ below. The decorator returns the same class that it is called on; no new
class is created.
If :func:`dataclass` is used just as a simple decorator with no parameters,
@@ -202,10 +202,10 @@ Module contents
def __init__(self, a: int, b: int = 0):
:exc:`TypeError` will be raised if a field without a default value
- follows a field with a default value. This is true either when this
+ follows a field with a default value. This is true whether this
occurs in a single class, or as a result of class inheritance.
-.. function:: field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, hash=None, compare=True, metadata=None, kw_only=MISSING):
+.. function:: field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, hash=None, compare=True, metadata=None, kw_only=MISSING)
For common and simple use cases, no other functionality is
required. There are, however, some dataclass features that
@@ -221,10 +221,9 @@ Module contents
c.mylist += [1, 2, 3]
As shown above, the :const:`MISSING` value is a sentinel object used to
- detect if the ``default`` and ``default_factory`` parameters are
- provided. This sentinel is used because ``None`` is a valid value
- for ``default``. No code should directly use the :const:`MISSING`
- value.
+ detect if some parameters are provided by the user. This sentinel is
+ used because ``None`` is a valid value for some parameters with
+ a distinct meaning. No code should directly use the :const:`MISSING` value.
The parameters to :func:`field` are:
@@ -308,7 +307,7 @@ Module contents
- ``default``, ``default_factory``, ``init``, ``repr``, ``hash``,
``compare``, ``metadata``, and ``kw_only`` have the identical
- meaning and values as they do in the :func:`field` declaration.
+ meaning and values as they do in the :func:`field` function.
Other attributes may exist, but they are private and must not be
inspected or relied on.
@@ -320,12 +319,15 @@ Module contents
Raises :exc:`TypeError` if not passed a dataclass or instance of one.
Does not return pseudo-fields which are ``ClassVar`` or ``InitVar``.
-.. function:: asdict(instance, *, dict_factory=dict)
+.. function:: asdict(obj, *, dict_factory=dict)
- Converts the dataclass ``instance`` to a dict (by using the
+ 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. For example::
+ lists, and tuples are recursed into. Other objects are copied with
+ :func:`copy.deepcopy`.
+
+ Example of using :func:`asdict` on nested dataclasses::
@dataclass
class Point:
@@ -342,21 +344,32 @@ Module contents
c = C([Point(0, 0), Point(10, 4)])
assert asdict(c) == {'mylist': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]}
- Raises :exc:`TypeError` if ``instance`` is not a dataclass instance.
+ To create a shallow copy, the following workaround may be used::
+
+ dict((field.name, getattr(obj, field.name)) for field in fields(obj))
-.. function:: astuple(instance, *, tuple_factory=tuple)
+ :func:`asdict` raises :exc:`TypeError` if ``obj`` is not a dataclass
+ instance.
- Converts the dataclass ``instance`` to a tuple (by using the
+.. function:: astuple(obj, *, tuple_factory=tuple)
+
+ 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.
+ tuples are recursed into. Other objects are copied with
+ :func:`copy.deepcopy`.
Continuing from the previous example::
assert astuple(p) == (10, 20)
assert astuple(c) == ([(0, 0), (10, 4)],)
- Raises :exc:`TypeError` if ``instance`` is not a dataclass instance.
+ To create a shallow copy, the following workaround may be used::
+
+ tuple(getattr(obj, field.name) for field in dataclasses.fields(obj))
+
+ :func:`astuple` raises :exc:`TypeError` if ``obj`` is not a dataclass
+ instance.
.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False)
@@ -393,10 +406,10 @@ Module contents
def add_one(self):
return self.x + 1
-.. function:: replace(instance, /, **changes)
+.. function:: replace(obj, /, **changes)
- Creates a new object of the same type of ``instance``, replacing
- fields with values from ``changes``. If ``instance`` is not a Data
+ Creates a new object of the same type as ``obj``, replacing
+ fields with values from ``changes``. If ``obj`` is not a Data
Class, raises :exc:`TypeError`. If values in ``changes`` do not
specify fields, raises :exc:`TypeError`.
@@ -421,7 +434,7 @@ Module contents
``replace()`` (or similarly named) method which handles instance
copying.
-.. function:: is_dataclass(class_or_instance)
+.. function:: is_dataclass(obj)
Return ``True`` if its parameter is a dataclass or an instance of one,
otherwise return ``False``.
@@ -462,6 +475,8 @@ Module contents
In a single dataclass, it is an error to specify more than one
field whose type is :const:`KW_ONLY`.
+ .. versionadded:: 3.10
+
.. exception:: FrozenInstanceError
Raised when an implicitly defined :meth:`__setattr__` or
@@ -491,6 +506,27 @@ depend on one or more other fields. For example::
def __post_init__(self):
self.c = self.a + self.b
+The :meth:`__init__` method generated by :func:`dataclass` does not call base
+class :meth:`__init__` methods. If the base class has an :meth:`__init__` method
+that has to be called, it is common to call this method in a
+:meth:`__post_init__` method::
+
+ @dataclass
+ class Rectangle:
+ height: float
+ width: float
+
+ @dataclass
+ class Square(Rectangle):
+ side: float
+
+ def __post_init__(self):
+ super().__init__(self.side, self.side)
+
+Note, however, that in general the dataclass-generated :meth:`__init__` methods
+don't need to be called, since the derived dataclass will take care of
+initializing all fields of any base class that is a dataclass itself.
+
See the section below on init-only variables for ways to pass
parameters to :meth:`__post_init__`. Also see the warning about how
:func:`replace` handles ``init=False`` fields.
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index dae0dd7aa55898..44f9de2307d168 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -27,6 +27,9 @@ on efficient attribute extraction for output formatting and manipulation.
Module :mod:`time`
Time access and conversions.
+ Module :mod:`zoneinfo`
+ Concrete time zones representing the IANA time zone database.
+
Package `dateutil `_
Third-party library with expanded time zone and parsing support.
@@ -2174,14 +2177,13 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
.. seealso::
- `dateutil.tz `_
+ :mod:`zoneinfo`
The :mod:`datetime` module has a basic :class:`timezone` class (for
handling arbitrary fixed offsets from UTC) and its :attr:`timezone.utc`
attribute (a UTC timezone instance).
- *dateutil.tz* library brings the *IANA timezone database*
- (also known as the Olson database) to Python, and its usage is
- recommended.
+ ``zoneinfo`` brings the *IANA timezone database* (also known as the Olson
+ database) to Python, and its usage is recommended.
`IANA timezone database `_
The Time Zone Database (often called tz, tzdata or zoneinfo) contains code
@@ -2357,8 +2359,8 @@ requires, and these work on all platforms with a standard C implementation.
| | decimal number. | | \(9) |
+-----------+--------------------------------+------------------------+-------+
| ``%f`` | Microsecond as a decimal | 000000, 000001, ..., | \(5) |
-| | number, zero-padded on the | 999999 | |
-| | left. | | |
+| | number, zero-padded to 6 | 999999 | |
+| | digits. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%z`` | UTC offset in the form | (empty), +0000, | \(6) |
| | ``±HHMM[SS[.ffffff]]`` (empty | -0400, +1030, | |
@@ -2373,7 +2375,7 @@ requires, and these work on all platforms with a standard C implementation.
+-----------+--------------------------------+------------------------+-------+
| ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7), |
| | (Sunday as the first day of | | \(9) |
-| | the week) as a zero padded | | |
+| | the week) as a zero-padded | | |
| | decimal number. All days in a | | |
| | new year preceding the first | | |
| | Sunday are considered to be in | | |
@@ -2381,10 +2383,10 @@ requires, and these work on all platforms with a standard C implementation.
+-----------+--------------------------------+------------------------+-------+
| ``%W`` | Week number of the year | 00, 01, ..., 53 | \(7), |
| | (Monday as the first day of | | \(9) |
-| | the week) as a decimal number. | | |
-| | All days in a new year | | |
-| | preceding the first Monday | | |
-| | are considered to be in | | |
+| | the week) as a zero-padded | | |
+| | decimal number. All days in a | | |
+| | new year preceding the first | | |
+| | Monday are considered to be in | | |
| | week 0. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%c`` | Locale's appropriate date and || Tue Aug 16 21:30:00 | \(1) |
@@ -2431,7 +2433,8 @@ incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`.
The full set of format codes supported varies across platforms, because Python
calls the platform C library's :func:`strftime` function, and platform
variations are common. To see the full set of format codes supported on your
-platform, consult the :manpage:`strftime(3)` documentation.
+platform, consult the :manpage:`strftime(3)` documentation. There are also
+differences between platforms in handling of unsupported format specifiers.
.. versionadded:: 3.6
``%G``, ``%u`` and ``%V`` were added.
@@ -2581,7 +2584,7 @@ Notes:
many other calendar systems.
.. [#] See R. H. van Gent's `guide to the mathematics of the ISO 8601 calendar
- `_
+ `_
for a good explanation.
.. [#] Passing ``datetime.strptime('Feb 29', '%b %d')`` will fail since ``1900`` is not a leap year.
diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst
index 57ae547b833cc0..ff01ae90f64257 100644
--- a/Doc/library/dbm.rst
+++ b/Doc/library/dbm.rst
@@ -216,7 +216,7 @@ supported.
contains them all::
k = db.firstkey()
- while k != None:
+ while k is not None:
print(k)
k = db.nextkey(k)
diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index e759c5cf23b9e7..47627c02561b94 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -571,9 +571,10 @@ Decimal objects
>>> Decimal(321).exp()
Decimal('2.561702493119680037517373933E+139')
- .. method:: from_float(f)
+ .. classmethod:: from_float(f)
- Classmethod that converts a float to a decimal number, exactly.
+ Alternative constructor that only accepts instances of :class:`float` or
+ :class:`int`.
Note `Decimal.from_float(0.1)` is not the same as `Decimal('0.1')`.
Since 0.1 is not exactly representable in binary floating point, the
diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst
index aa08988c8b36f7..a5ee0fb5389793 100644
--- a/Doc/library/difflib.rst
+++ b/Doc/library/difflib.rst
@@ -149,7 +149,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
contains a good example of its use.
-.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n')
+.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n')
Compare *a* and *b* (lists of strings); return a delta (a :term:`generator`
generating the delta lines) in context diff format.
@@ -279,7 +279,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
emu
-.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n')
+.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n')
Compare *a* and *b* (lists of strings); return a delta (a :term:`generator`
generating the delta lines) in unified diff format.
@@ -321,7 +321,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
See :ref:`difflib-interface` for a more detailed example.
-.. function:: diff_bytes(dfunc, a, b, fromfile=b'', tofile=b'', fromfiledate=b'', tofiledate=b'', n=3, lineterm=b'\\n')
+.. function:: diff_bytes(dfunc, a, b, fromfile=b'', tofile=b'', fromfiledate=b'', tofiledate=b'', n=3, lineterm=b'\n')
Compare *a* and *b* (lists of bytes objects) using *dfunc*; yield a
sequence of delta lines (also bytes) in the format returned by *dfunc*.
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 0491a9d4a072bf..1df281a7e3d2b6 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -232,15 +232,17 @@ operation is being performed, so the intermediate analysis object isn't useful:
.. function:: findlinestarts(code)
- This generator function uses the ``co_firstlineno`` and ``co_lnotab``
- attributes of the code object *code* to find the offsets which are starts of
+ This generator function uses the ``co_lines`` method
+ of the code object *code* to find the offsets which are starts of
lines in the source code. They are generated as ``(offset, lineno)`` pairs.
- See :source:`Objects/lnotab_notes.txt` for the ``co_lnotab`` format and
- how to decode it.
.. versionchanged:: 3.6
Line numbers can be decreasing. Before, they were always increasing.
+ .. versionchanged:: 3.10
+ The :pep:`626` ``co_lines`` method is used instead of the ``co_firstlineno``
+ and ``co_lnotab`` attributes of the code object.
+
.. function:: findlabels(code)
@@ -591,8 +593,8 @@ the original TOS1.
.. opcode:: GET_ANEXT
- Implements ``PUSH(get_awaitable(TOS.__anext__()))``. See ``GET_AWAITABLE``
- for details about ``get_awaitable``
+ Pushes ``get_awaitable(TOS.__anext__())`` to the stack. See
+ ``GET_AWAITABLE`` for details about ``get_awaitable``.
.. versionadded:: 3.5
@@ -770,17 +772,20 @@ iterations of the loop.
.. opcode:: MATCH_MAPPING
- If TOS is an instance of :class:`collections.abc.Mapping`, push ``True`` onto
- the stack. Otherwise, push ``False``.
+ If TOS is an instance of :class:`collections.abc.Mapping` (or, more technically: if
+ it has the :const:`Py_TPFLAGS_MAPPING` flag set in its
+ :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push
+ ``False``.
.. versionadded:: 3.10
.. opcode:: MATCH_SEQUENCE
- If TOS is an instance of :class:`collections.abc.Sequence` and is *not* an
- instance of :class:`str`/:class:`bytes`/:class:`bytearray`, push ``True``
- onto the stack. Otherwise, push ``False``.
+ If TOS is an instance of :class:`collections.abc.Sequence` and is *not* an instance
+ of :class:`str`/:class:`bytes`/:class:`bytearray` (or, more technically: if it has
+ the :const:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`),
+ push ``True`` onto the stack. Otherwise, push ``False``.
.. versionadded:: 3.10
@@ -1249,9 +1254,8 @@ All of the following opcodes use their arguments.
.. opcode:: GEN_START (kind)
- Pops TOS. If TOS was not ``None``, raises an exception. The ``kind``
- operand corresponds to the type of generator or coroutine and determines
- the error message. The legal kinds are 0 for generator, 1 for coroutine,
+ Pops TOS. The ``kind`` operand corresponds to the type of generator or
+ coroutine. The legal kinds are 0 for generator, 1 for coroutine,
and 2 for async generator.
.. versionadded:: 3.10
diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst
index a77322f83acbde..dbb54c99133f39 100644
--- a/Doc/library/doctest.rst
+++ b/Doc/library/doctest.rst
@@ -288,10 +288,6 @@ strings are treated as if they were docstrings. In output, a key ``K`` in
Any classes found are recursively searched similarly, to test docstrings in
their contained methods and nested classes.
-.. impl-detail::
- Prior to version 3.4, extension modules written in C were not fully
- searched by doctest.
-
.. _doctest-finding-examples:
@@ -568,41 +564,35 @@ doctest decides whether actual output matches an example's expected output:
.. data:: IGNORE_EXCEPTION_DETAIL
- When specified, an example that expects an exception passes if an exception of
- the expected type is raised, even if the exception detail does not match. For
- example, an example expecting ``ValueError: 42`` will pass if the actual
- exception raised is ``ValueError: 3*14``, but will fail, e.g., if
- :exc:`TypeError` is raised.
+ When specified, doctests expecting exceptions pass so long as an exception
+ of the expected type is raised, even if the details
+ (message and fully-qualified exception name) don't match.
+
+ For example, an example expecting ``ValueError: 42`` will pass if the actual
+ exception raised is ``ValueError: 3*14``, but will fail if, say, a
+ :exc:`TypeError` is raised instead.
+ It will also ignore any fully-qualified name included before the
+ exception class, which can vary between implementations and versions
+ of Python and the code/libraries in use.
+ Hence, all three of these variations will work with the flag specified:
- It will also ignore the module name used in Python 3 doctest reports. Hence
- both of these variations will work with the flag specified, regardless of
- whether the test is run under Python 2.7 or Python 3.2 (or later versions)::
+ .. code-block:: pycon
- >>> raise CustomError('message')
+ >>> raise Exception('message')
Traceback (most recent call last):
- CustomError: message
+ Exception: message
- >>> raise CustomError('message')
+ >>> raise Exception('message')
Traceback (most recent call last):
- my_module.CustomError: message
+ builtins.Exception: message
- Note that :const:`ELLIPSIS` can also be used to ignore the
- details of the exception message, but such a test may still fail based
- on whether or not the module details are printed as part of the
- exception name. Using :const:`IGNORE_EXCEPTION_DETAIL` and the details
- from Python 2.3 is also the only clear way to write a doctest that doesn't
- care about the exception detail yet continues to pass under Python 2.3 or
- earlier (those releases do not support :ref:`doctest directives
- ` and ignore them as irrelevant comments). For example::
-
- >>> (1, 2)[3] = 'moo'
+ >>> raise Exception('message')
Traceback (most recent call last):
- File "", line 1, in
- TypeError: object doesn't support item assignment
+ __main__.Exception: message
- passes under Python 2.3 and later Python versions with the flag specified,
- even though the detail
- changed in Python 2.4 to say "does not" instead of "doesn't".
+ Note that :const:`ELLIPSIS` can also be used to ignore the
+ details of the exception message, but such a test may still fail based
+ on whether the module name is present or matches exactly.
.. versionchanged:: 3.2
:const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information relating
@@ -719,36 +709,51 @@ above.
An example's doctest directives modify doctest's behavior for that single
example. Use ``+`` to enable the named behavior, or ``-`` to disable it.
-For example, this test passes::
+For example, this test passes:
- >>> print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE
+.. doctest::
+ :no-trim-doctest-flags:
+
+ >>> print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Without the directive it would fail, both because the actual output doesn't have
two blanks before the single-digit list elements, and because the actual output
is on a single line. This test also passes, and also requires a directive to do
-so::
+so:
+
+.. doctest::
+ :no-trim-doctest-flags:
- >>> print(list(range(20))) # doctest: +ELLIPSIS
+ >>> print(list(range(20))) # doctest: +ELLIPSIS
[0, 1, ..., 18, 19]
Multiple directives can be used on a single physical line, separated by
-commas::
+commas:
- >>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+.. doctest::
+ :no-trim-doctest-flags:
+
+ >>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
[0, 1, ..., 18, 19]
If multiple directive comments are used for a single example, then they are
-combined::
+combined:
+
+.. doctest::
+ :no-trim-doctest-flags:
- >>> print(list(range(20))) # doctest: +ELLIPSIS
- ... # doctest: +NORMALIZE_WHITESPACE
+ >>> print(list(range(20))) # doctest: +ELLIPSIS
+ ... # doctest: +NORMALIZE_WHITESPACE
[0, 1, ..., 18, 19]
As the previous example shows, you can add ``...`` lines to your example
containing only directives. This can be useful when an example is too long for
-a directive to comfortably fit on the same line::
+a directive to comfortably fit on the same line:
+
+.. doctest::
+ :no-trim-doctest-flags:
>>> print(list(range(5)) + list(range(10, 20)) + list(range(30, 40)))
... # doctest: +ELLIPSIS
@@ -786,25 +791,25 @@ instead. Another is to do ::
>>> d
['Harry', 'Hermione']
-.. note::
-
- Before Python 3.6, when printing a dict, Python did not guarantee that
- the key-value pairs was printed in any particular order.
-
There are others, but you get the idea.
-Another bad idea is to print things that embed an object address, like ::
+Another bad idea is to print things that embed an object address, like
+
+.. doctest::
- >>> id(1.0) # certain to fail some of the time
+ >>> id(1.0) # certain to fail some of the time # doctest: +SKIP
7948648
>>> class C: pass
- >>> C() # the default repr() for instances embeds an address
- <__main__.C instance at 0x00AC18F0>
+ >>> C() # the default repr() for instances embeds an address # doctest: +SKIP
+
+
+The :const:`ELLIPSIS` directive gives a nice approach for the last example:
-The :const:`ELLIPSIS` directive gives a nice approach for the last example::
+.. doctest::
+ :no-trim-doctest-flags:
- >>> C() #doctest: +ELLIPSIS
- <__main__.C instance at 0x...>
+ >>> C() # doctest: +ELLIPSIS
+
Floating-point numbers are also subject to small output variations across
platforms, because Python defers to the platform C library for float formatting,
diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst
index 38fda23bd8237f..adbe6c1c7d29b8 100644
--- a/Doc/library/email.charset.rst
+++ b/Doc/library/email.charset.rst
@@ -58,9 +58,9 @@ Import this class from the :mod:`email.charset` module.
.. attribute:: header_encoding
If the character set must be encoded before it can be used in an email
- header, this attribute will be set to ``Charset.QP`` (for
- quoted-printable), ``Charset.BASE64`` (for base64 encoding), or
- ``Charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise,
+ header, this attribute will be set to ``charset.QP`` (for
+ quoted-printable), ``charset.BASE64`` (for base64 encoding), or
+ ``charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise,
it will be ``None``.
@@ -68,7 +68,7 @@ Import this class from the :mod:`email.charset` module.
Same as *header_encoding*, but describes the encoding for the mail
message's body, which indeed may be different than the header encoding.
- ``Charset.SHORTEST`` is not allowed for *body_encoding*.
+ ``charset.SHORTEST`` is not allowed for *body_encoding*.
.. attribute:: output_charset
@@ -175,9 +175,9 @@ new entries to the global character set, alias, and codec registries:
*charset* is the input character set, and must be the canonical name of a
character set.
- Optional *header_enc* and *body_enc* is either ``Charset.QP`` for
- quoted-printable, ``Charset.BASE64`` for base64 encoding,
- ``Charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding,
+ Optional *header_enc* and *body_enc* is either ``charset.QP`` for
+ quoted-printable, ``charset.BASE64`` for base64 encoding,
+ ``charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding,
or ``None`` for no encoding. ``SHORTEST`` is only valid for
*header_enc*. The default is ``None`` for no encoding.
diff --git a/Doc/library/email.header.rst b/Doc/library/email.header.rst
index 07152c224f2ff0..e093f138936b36 100644
--- a/Doc/library/email.header.rst
+++ b/Doc/library/email.header.rst
@@ -116,7 +116,7 @@ Here is the :class:`Header` class description:
if *s* is a byte string.
- .. method:: encode(splitchars=';, \\t', maxlinelen=None, linesep='\\n')
+ .. method:: encode(splitchars=';, \t', maxlinelen=None, linesep='\n')
Encode a message header into an RFC-compliant format, possibly wrapping
long lines and encapsulating non-ASCII parts in base64 or quoted-printable
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
index b5f9c2f08b1873..7d166bfb1fcc61 100644
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -13,617 +13,1200 @@
**Source code:** :source:`Lib/enum.py`
-.. sidebar:: Important
+----------------
- This page contains the API reference information. For tutorial
- information and discussion of more advanced topics, see
+An enumeration is a set of symbolic names (members) bound to unique,
+constant values. Within an enumeration, the members can be compared
+by identity, and the enumeration itself can be iterated over.
- * :ref:`Basic Tutorial `
- * :ref:`Advanced Tutorial `
- * :ref:`Enum Cookbook `
+.. note:: Case of Enum Members
-----------------
+ Because Enums are used to represent constants we recommend using
+ UPPER_CASE names for enum members, and will be using that style
+ in our examples.
-An enumeration:
-* is a set of symbolic names (members) bound to unique values
-* can be iterated over to return its members in definition order
-* uses :meth:`call` syntax to return members by value
-* uses :meth:`index` syntax to return members by name
+Module Contents
+---------------
-Enumerations are created either by using the :keyword:`class` syntax, or by
-using function-call syntax::
+This module defines four enumeration classes that can be used to define unique
+sets of names and values: :class:`Enum`, :class:`IntEnum`, :class:`Flag`, and
+:class:`IntFlag`. It also defines one decorator, :func:`unique`, and one
+helper, :class:`auto`.
- >>> from enum import Enum
+.. class:: Enum
- >>> # class syntax
- >>> class Color(Enum):
- ... RED = 1
- ... GREEN = 2
- ... BLUE = 3
+ Base class for creating enumerated constants. See section
+ `Functional API`_ for an alternate construction syntax.
- >>> # functional syntax
- >>> Color = Enum('Color', ['RED', 'GREEN', 'BLUE'])
+.. class:: IntEnum
-Even though we can use the :keyword:`class` syntax to create Enums, Enums
-are not normal Python classes. See
-:ref:`How are Enums different? ` for more details.
+ Base class for creating enumerated constants that are also
+ subclasses of :class:`int`.
-.. note:: Nomenclature
+.. class:: IntFlag
- - The class :class:`Color` is an *enumeration* (or *enum*)
- - The attributes :attr:`Color.RED`, :attr:`Color.GREEN`, etc., are
- *enumeration members* (or *enum members*) and are functionally constants.
- - The enum members have *names* and *values* (the name of
- :attr:`Color.RED` is ``RED``, the value of :attr:`Color.BLUE` is
- ``3``, etc.)
+ Base class for creating enumerated constants that can be combined using
+ the bitwise operators without losing their :class:`IntFlag` membership.
+ :class:`IntFlag` members are also subclasses of :class:`int`.
+.. class:: Flag
-Module Contents
----------------
+ Base class for creating enumerated constants that can be combined using
+ the bitwise operations without losing their :class:`Flag` membership.
- :class:`EnumType`
+.. function:: unique
+ :noindex:
- The ``type`` for Enum and its subclasses.
+ Enum class decorator that ensures only one name is bound to any one value.
- :class:`Enum`
+.. class:: auto
- Base class for creating enumerated constants.
+ Instances are replaced with an appropriate value for Enum members. By default, the initial value starts at 1.
- :class:`IntEnum`
+.. versionadded:: 3.6 ``Flag``, ``IntFlag``, ``auto``
- Base class for creating enumerated constants that are also
- subclasses of :class:`int`.
- :class:`StrEnum`
+Creating an Enum
+----------------
- Base class for creating enumerated constants that are also
- subclasses of :class:`str`.
+Enumerations are created using the :keyword:`class` syntax, which makes them
+easy to read and write. An alternative creation method is described in
+`Functional API`_. To define an enumeration, subclass :class:`Enum` as
+follows::
- :class:`Flag`
+ >>> from enum import Enum
+ >>> class Color(Enum):
+ ... RED = 1
+ ... GREEN = 2
+ ... BLUE = 3
+ ...
- Base class for creating enumerated constants that can be combined using
- the bitwise operations without losing their :class:`Flag` membership.
+.. note:: Enum member values
- :class:`IntFlag`
+ Member values can be anything: :class:`int`, :class:`str`, etc.. If
+ the exact value is unimportant you may use :class:`auto` instances and an
+ appropriate value will be chosen for you. Care must be taken if you mix
+ :class:`auto` with other values.
- Base class for creating enumerated constants that can be combined using
- the bitwise operators without losing their :class:`IntFlag` membership.
- :class:`IntFlag` members are also subclasses of :class:`int`.
+.. note:: Nomenclature
- :class:`FlagBoundary`
+ - The class :class:`Color` is an *enumeration* (or *enum*)
+ - The attributes :attr:`Color.RED`, :attr:`Color.GREEN`, etc., are
+ *enumeration members* (or *enum members*) and are functionally constants.
+ - The enum members have *names* and *values* (the name of
+ :attr:`Color.RED` is ``RED``, the value of :attr:`Color.BLUE` is
+ ``3``, etc.)
- An enumeration with the values ``STRICT``, ``CONFORM``, ``EJECT``, and
- ``KEEP`` which allows for more fine-grained control over how invalid values
- are dealt with in an enumeration.
+.. note::
- :class:`auto`
+ Even though we use the :keyword:`class` syntax to create Enums, Enums
+ are not normal Python classes. See `How are Enums different?`_ for
+ more details.
- Instances are replaced with an appropriate value for Enum members.
- :class:`StrEnum` defaults to the lower-cased version of the member name,
- while other Enums default to 1 and increase from there.
+Enumeration members have human readable string representations::
- :func:`global_enum`
+ >>> print(Color.RED)
+ Color.RED
- :class:`Enum` class decorator to apply the appropriate global `__repr__`,
- and export its members into the global name space.
+...while their ``repr`` has more information::
- :func:`property`
+ >>> print(repr(Color.RED))
+
- Allows :class:`Enum` members to have attributes without conflicting with
- other members' names.
+The *type* of an enumeration member is the enumeration it belongs to::
- :func:`unique`
+ >>> type(Color.RED)
+
+ >>> isinstance(Color.GREEN, Color)
+ True
+ >>>
- Enum class decorator that ensures only one name is bound to any one value.
+Enum members also have a property that contains just their item name::
+ >>> print(Color.RED.name)
+ RED
-.. versionadded:: 3.6 ``Flag``, ``IntFlag``, ``auto``
-.. versionadded:: 3.10 ``StrEnum``
+Enumerations support iteration, in definition order::
+ >>> class Shake(Enum):
+ ... VANILLA = 7
+ ... CHOCOLATE = 4
+ ... COOKIES = 9
+ ... MINT = 3
+ ...
+ >>> for shake in Shake:
+ ... print(shake)
+ ...
+ Shake.VANILLA
+ Shake.CHOCOLATE
+ Shake.COOKIES
+ Shake.MINT
-Data Types
-----------
+Enumeration members are hashable, so they can be used in dictionaries and sets::
+ >>> apples = {}
+ >>> apples[Color.RED] = 'red delicious'
+ >>> apples[Color.GREEN] = 'granny smith'
+ >>> apples == {Color.RED: 'red delicious', Color.GREEN: 'granny smith'}
+ True
-.. class:: EnumType
- *EnumType* is the :term:`metaclass` for *enum* enumerations. It is possible
- to subclass *EnumType* -- see :ref:`Subclassing EnumType `
- for details.
+Programmatic access to enumeration members and their attributes
+---------------------------------------------------------------
- .. method:: EnumType.__contains__(cls, member)
+Sometimes it's useful to access members in enumerations programmatically (i.e.
+situations where ``Color.RED`` won't do because the exact color is not known
+at program-writing time). ``Enum`` allows such access::
- Returns ``True`` if member belongs to the ``cls``::
+ >>> Color(1)
+
+ >>> Color(3)
+
- >>> some_var = Color.RED
- >>> some_var in Color
- True
+If you want to access enum members by *name*, use item access::
- .. note::
+ >>> Color['RED']
+
+ >>> Color['GREEN']
+
- In Python 3.12 it will be possible to check for member values and not
- just members; until then, a ``TypeError`` will be raised if a
- non-Enum-member is used in a containment check.
+If you have an enum member and need its :attr:`name` or :attr:`value`::
- .. method:: EnumType.__dir__(cls)
+ >>> member = Color.RED
+ >>> member.name
+ 'RED'
+ >>> member.value
+ 1
- Returns ``['__class__', '__doc__', '__members__', '__module__']`` and the
- names of the members in *cls*::
- >>> dir(Color)
- ['BLUE', 'GREEN', 'RED', '__class__', '__doc__', '__members__', '__module__']
+Duplicating enum members and values
+-----------------------------------
- .. method:: EnumType.__getattr__(cls, name)
+Having two enum members with the same name is invalid::
- Returns the Enum member in *cls* matching *name*, or raises an :exc:`AttributeError`::
+ >>> class Shape(Enum):
+ ... SQUARE = 2
+ ... SQUARE = 3
+ ...
+ Traceback (most recent call last):
+ ...
+ TypeError: Attempted to reuse key: 'SQUARE'
- >>> Color.GREEN
- Color.GREEN
+However, two enum members are allowed to have the same value. Given two members
+A and B with the same value (and A defined first), B is an alias to A. By-value
+lookup of the value of A and B will return A. By-name lookup of B will also
+return A::
- .. method:: EnumType.__getitem__(cls, name)
+ >>> class Shape(Enum):
+ ... SQUARE = 2
+ ... DIAMOND = 1
+ ... CIRCLE = 3
+ ... ALIAS_FOR_SQUARE = 2
+ ...
+ >>> Shape.SQUARE
+
+ >>> Shape.ALIAS_FOR_SQUARE
+
+ >>> Shape(2)
+
- Returns the Enum member in *cls* matching *name*, or raises an :exc:`KeyError`::
+.. note::
- >>> Color['BLUE']
- Color.BLUE
+ Attempting to create a member with the same name as an already
+ defined attribute (another member, a method, etc.) or attempting to create
+ an attribute with the same name as a member is not allowed.
- .. method:: EnumType.__iter__(cls)
- Returns each member in *cls* in definition order::
+Ensuring unique enumeration values
+----------------------------------
- >>> list(Color)
- [Color.RED, Color.GREEN, Color.BLUE]
+By default, enumerations allow multiple names as aliases for the same value.
+When this behavior isn't desired, the following decorator can be used to
+ensure each value is used only once in the enumeration:
- .. method:: EnumType.__len__(cls)
+.. decorator:: unique
- Returns the number of member in *cls*::
+A :keyword:`class` decorator specifically for enumerations. It searches an
+enumeration's :attr:`__members__` gathering any aliases it finds; if any are
+found :exc:`ValueError` is raised with the details::
+
+ >>> from enum import Enum, unique
+ >>> @unique
+ ... class Mistake(Enum):
+ ... ONE = 1
+ ... TWO = 2
+ ... THREE = 3
+ ... FOUR = 3
+ ...
+ Traceback (most recent call last):
+ ...
+ ValueError: duplicate values found in : FOUR -> THREE
+
+
+Using automatic values
+----------------------
+
+If the exact value is unimportant you can use :class:`auto`::
+
+ >>> from enum import Enum, auto
+ >>> class Color(Enum):
+ ... RED = auto()
+ ... BLUE = auto()
+ ... GREEN = auto()
+ ...
+ >>> list(Color)
+ [, , ]
+
+The values are chosen by :func:`_generate_next_value_`, which can be
+overridden::
+
+ >>> class AutoName(Enum):
+ ... def _generate_next_value_(name, start, count, last_values):
+ ... return name
+ ...
+ >>> class Ordinal(AutoName):
+ ... NORTH = auto()
+ ... SOUTH = auto()
+ ... EAST = auto()
+ ... WEST = auto()
+ ...
+ >>> list(Ordinal)
+ [, , , ]
- >>> len(Color)
- 3
+.. note::
- .. method:: EnumType.__reversed__(cls)
+ The goal of the default :meth:`_generate_next_value_` method is to provide
+ the next :class:`int` in sequence with the last :class:`int` provided, but
+ the way it does this is an implementation detail and may change.
- Returns each member in *cls* in reverse definition order::
+.. note::
- >>> list(reversed(Color))
- [Color.BLUE, Color.GREEN, Color.RED]
+ The :meth:`_generate_next_value_` method must be defined before any members.
+Iteration
+---------
-.. class:: Enum
+Iterating over the members of an enum does not provide the aliases::
+
+ >>> list(Shape)
+ [, , ]
+
+The special attribute ``__members__`` is a read-only ordered mapping of names
+to members. It includes all names defined in the enumeration, including the
+aliases::
+
+ >>> for name, member in Shape.__members__.items():
+ ... name, member
+ ...
+ ('SQUARE', )
+ ('DIAMOND', )
+ ('CIRCLE', )
+ ('ALIAS_FOR_SQUARE', )
- *Enum* is the base class for all *enum* enumerations.
+The ``__members__`` attribute can be used for detailed programmatic access to
+the enumeration members. For example, finding all the aliases::
- .. attribute:: Enum.name
+ >>> [name for name, member in Shape.__members__.items() if member.name != name]
+ ['ALIAS_FOR_SQUARE']
- The name used to define the ``Enum`` member::
- >>> Color.BLUE.name
- 'BLUE'
+Comparisons
+-----------
- .. attribute:: Enum.value
+Enumeration members are compared by identity::
- The value given to the ``Enum`` member::
+ >>> Color.RED is Color.RED
+ True
+ >>> Color.RED is Color.BLUE
+ False
+ >>> Color.RED is not Color.BLUE
+ True
- >>> Color.RED.value
- 1
+Ordered comparisons between enumeration values are *not* supported. Enum
+members are not integers (but see `IntEnum`_ below)::
+
+ >>> Color.RED < Color.BLUE
+ Traceback (most recent call last):
+ File "", line 1, in
+ TypeError: '<' not supported between instances of 'Color' and 'Color'
+
+Equality comparisons are defined though::
+
+ >>> Color.BLUE == Color.RED
+ False
+ >>> Color.BLUE != Color.RED
+ True
+ >>> Color.BLUE == Color.BLUE
+ True
- .. note:: Enum member values
+Comparisons against non-enumeration values will always compare not equal
+(again, :class:`IntEnum` was explicitly designed to behave differently, see
+below)::
- Member values can be anything: :class:`int`, :class:`str`, etc.. If
- the exact value is unimportant you may use :class:`auto` instances and an
- appropriate value will be chosen for you. Care must be taken if you mix
- :class:`auto` with other values.
+ >>> Color.BLUE == 2
+ False
- .. attribute:: Enum._ignore_
- ``_ignore_`` is only used during creation and is removed from the
- enumeration once that is complete.
+Allowed members and attributes of enumerations
+----------------------------------------------
- ``_ignore_`` is a list of names that will not become members, and whose
- names will also be removed from the completed enumeration. See
- :ref:`TimePeriod ` for an example.
+The examples above use integers for enumeration values. Using integers is
+short and handy (and provided by default by the `Functional API`_), but not
+strictly enforced. In the vast majority of use-cases, one doesn't care what
+the actual value of an enumeration is. But if the value *is* important,
+enumerations can have arbitrary values.
- .. method:: Enum.__call__(cls, value, names=None, \*, module=None, qualname=None, type=None, start=1, boundary=None)
+Enumerations are Python classes, and can have methods and special methods as
+usual. If we have this enumeration::
- This method is called in two different ways:
+ >>> class Mood(Enum):
+ ... FUNKY = 1
+ ... HAPPY = 3
+ ...
+ ... def describe(self):
+ ... # self is the member here
+ ... return self.name, self.value
+ ...
+ ... def __str__(self):
+ ... return 'my custom str! {0}'.format(self.value)
+ ...
+ ... @classmethod
+ ... def favorite_mood(cls):
+ ... # cls here is the enumeration
+ ... return cls.HAPPY
+ ...
- * to look up an existing member:
+Then::
- :cls: The enum class being called.
- :value: The value to lookup.
-
- * to use the ``cls`` enum to create a new enum:
-
- :cls: The enum class being called.
- :value: The name of the new Enum to create.
- :names: The names/values of the members for the new Enum.
- :module: The name of the module the new Enum is created in.
- :qualname: The actual location in the module where this Enum can be found.
- :type: A mix-in type for the new Enum.
- :start: The first integer value for the Enum (used by :class:`auto`)
- :boundary: How to handle out-of-range values from bit operations (:class:`Flag` only)
-
- .. method:: Enum.__dir__(self)
-
- Returns ``['__class__', '__doc__', '__module__', 'name', 'value']`` and
- any public methods defined on *self.__class__*::
-
- >>> from datetime import date
- >>> class Weekday(Enum):
- ... MONDAY = 1
- ... TUESDAY = 2
- ... WEDNESDAY = 3
- ... THURSDAY = 4
- ... FRIDAY = 5
- ... SATURDAY = 6
- ... SUNDAY = 7
- ... @classmethod
- ... def today(cls):
- ... print('today is %s' % cls(date.today.isoweekday).naem)
- >>> dir(Weekday.SATURDAY)
- ['__class__', '__doc__', '__module__', 'name', 'today', 'value']
-
- .. method:: Enum._generate_next_value_(name, start, count, last_values)
-
- :name: The name of the member being defined (e.g. 'RED').
- :start: The start value for the Enum; the default is 1.
- :count: The number of members currently defined, not including this one.
- :last_values: A list of the previous values.
-
- A *staticmethod* that is used to determine the next value returned by
- :class:`auto`::
-
- >>> from enum import auto
- >>> class PowersOfThree(Enum):
- ... @staticmethod
- ... def _generate_next_value_(name, start, count, last_values):
- ... return (count + 1) * 3
- ... FIRST = auto()
- ... SECOND = auto()
- >>> PowersOfThree.SECOND.value
- 6
-
- .. method:: Enum._missing_(cls, value)
-
- A *classmethod* for looking up values not found in *cls*. By default it
- does nothing, but can be overridden to implement custom search behavior::
-
- >>> from enum import StrEnum
- >>> class Build(StrEnum):
- ... DEBUG = auto()
- ... OPTIMIZED = auto()
- ... @classmethod
- ... def _missing_(cls, value):
- ... value = value.lower()
- ... for member in cls:
- ... if member.value == value:
- ... return member
- ... return None
- >>> Build.DEBUG.value
- 'debug'
- >>> Build('deBUG')
- Build.DEBUG
-
- .. method:: Enum.__repr__(self)
-
- Returns the string used for *repr()* calls. By default, returns the
- *Enum* name and the member name, but can be overridden::
-
- >>> class OldStyle(Enum):
- ... RETRO = auto()
- ... OLD_SCHOOl = auto()
- ... YESTERYEAR = auto()
- ... def __repr__(self):
- ... cls_name = self.__class__.__name__
- ... return f'<{cls_name}.{self.name}: {self.value}>'
- >>> OldStyle.RETRO
-
-
- .. method:: Enum.__str__(self)
-
- Returns the string used for *str()* calls. By default, returns the
- member name, but can be overridden::
-
- >>> class OldStyle(Enum):
- ... RETRO = auto()
- ... OLD_SCHOOl = auto()
- ... YESTERYEAR = auto()
- ... def __str__(self):
- ... cls_name = self.__class__.__name__
- ... return f'{cls_name}.{self.name}'
- >>> OldStyle.RETRO
- OldStyle.RETRO
+ >>> Mood.favorite_mood()
+
+ >>> Mood.HAPPY.describe()
+ ('HAPPY', 3)
+ >>> str(Mood.FUNKY)
+ 'my custom str! 1'
+
+The rules for what is allowed are as follows: names that start and end with
+a single underscore are reserved by enum and cannot be used; all other
+attributes defined within an enumeration will become members of this
+enumeration, with the exception of special methods (:meth:`__str__`,
+:meth:`__add__`, etc.), descriptors (methods are also descriptors), and
+variable names listed in :attr:`_ignore_`.
+
+Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__` then
+any value(s) given to the enum member will be passed into those methods.
+See `Planet`_ for an example.
+
+
+Restricted Enum subclassing
+---------------------------
+
+A new :class:`Enum` class must have one base Enum class, up to one concrete
+data type, and as many :class:`object`-based mixin classes as needed. The
+order of these base classes is::
+
+ class EnumName([mix-in, ...,] [data-type,] base-enum):
+ pass
+
+Also, subclassing an enumeration is allowed only if the enumeration does not define
+any members. So this is forbidden::
+
+ >>> class MoreColor(Color):
+ ... PINK = 17
+ ...
+ Traceback (most recent call last):
+ ...
+ TypeError: MoreColor: cannot extend enumeration 'Color'
+
+But this is allowed::
+
+ >>> class Foo(Enum):
+ ... def some_behavior(self):
+ ... pass
+ ...
+ >>> class Bar(Foo):
+ ... HAPPY = 1
+ ... SAD = 2
+ ...
+
+Allowing subclassing of enums that define members would lead to a violation of
+some important invariants of types and instances. On the other hand, it makes
+sense to allow sharing some common behavior between a group of enumerations.
+(See `OrderedEnum`_ for an example.)
+
+
+Pickling
+--------
+
+Enumerations can be pickled and unpickled::
+
+ >>> from test.test_enum import Fruit
+ >>> from pickle import dumps, loads
+ >>> Fruit.TOMATO is loads(dumps(Fruit.TOMATO))
+ True
+
+The usual restrictions for pickling apply: picklable enums must be defined in
+the top level of a module, since unpickling requires them to be importable
+from that module.
.. note::
- Using :class:`auto` with :class:`Enum` results in integers of increasing value,
- starting with ``1``.
+ With pickle protocol version 4 it is possible to easily pickle enums
+ nested in other classes.
+It is possible to modify how Enum members are pickled/unpickled by defining
+:meth:`__reduce_ex__` in the enumeration class.
-.. class:: IntEnum
- *IntEnum* is the same as *Enum*, but its members are also integers and can be
- used anywhere that an integer can be used. If any integer operation is performed
- with an *IntEnum* member, the resulting value loses its enumeration status.
-
- >>> from enum import IntEnum
- >>> class Numbers(IntEnum):
- ... ONE = 1
- ... TWO = 2
- ... THREE = 3
- >>> Numbers.THREE
- Numbers.THREE
- >>> Numbers.ONE + Numbers.TWO
- 3
- >>> Numbers.THREE + 5
- 8
- >>> Numbers.THREE == 3
- True
+Functional API
+--------------
-.. note::
+The :class:`Enum` class is callable, providing the following functional API::
- Using :class:`auto` with :class:`IntEnum` results in integers of increasing value,
- starting with ``1``.
+ >>> Animal = Enum('Animal', 'ANT BEE CAT DOG')
+ >>> Animal
+
+ >>> Animal.ANT
+
+ >>> Animal.ANT.value
+ 1
+ >>> list(Animal)
+ [, , , ]
+The semantics of this API resemble :class:`~collections.namedtuple`. The first
+argument of the call to :class:`Enum` is the name of the enumeration.
-.. class:: StrEnum
+The second argument is the *source* of enumeration member names. It can be a
+whitespace-separated string of names, a sequence of names, a sequence of
+2-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to
+values. The last two options enable assigning arbitrary values to
+enumerations; the others auto-assign increasing integers starting with 1 (use
+the ``start`` parameter to specify a different starting value). A
+new class derived from :class:`Enum` is returned. In other words, the above
+assignment to :class:`Animal` is equivalent to::
- *StrEnum* is the same as *Enum*, but its members are also strings and can be used
- in most of the same places that a string can be used. The result of any string
- operation performed on or with a *StrEnum* member is not part of the enumeration.
+ >>> class Animal(Enum):
+ ... ANT = 1
+ ... BEE = 2
+ ... CAT = 3
+ ... DOG = 4
+ ...
- .. note:: There are places in the stdlib that check for an exact :class:`str`
- instead of a :class:`str` subclass (i.e. ``type(unknown) == str``
- instead of ``isinstance(str, unknown)``), and in those locations you
- will need to use ``str(StrEnum.member)``.
+The reason for defaulting to ``1`` as the starting number and not ``0`` is
+that ``0`` is ``False`` in a boolean sense, but enum members all evaluate
+to ``True``.
+Pickling enums created with the functional API can be tricky as frame stack
+implementation details are used to try and figure out which module the
+enumeration is being created in (e.g. it will fail if you use a utility
+function in separate module, and also may not work on IronPython or Jython).
+The solution is to specify the module name explicitly as follows::
-.. note::
+ >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)
- Using :class:`auto` with :class:`StrEnum` results in values of the member name,
- lower-cased.
+.. warning::
+ If ``module`` is not supplied, and Enum cannot determine what it is,
+ the new Enum members will not be unpicklable; to keep errors closer to
+ the source, pickling will be disabled.
-.. class:: Flag
+The new pickle protocol 4 also, in some circumstances, relies on
+:attr:`~definition.__qualname__` being set to the location where pickle will be able
+to find the class. For example, if the class was made available in class
+SomeData in the global scope::
- *Flag* members support the bitwise operators ``&`` (*AND*), ``|`` (*OR*),
- ``^`` (*XOR*), and ``~`` (*INVERT*); the results of those operators are members
- of the enumeration.
+ >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal')
- .. method:: __contains__(self, value)
+The complete signature is::
- Returns *True* if value is in self::
+ Enum(value='NewEnumName', names=<...>, *, module='...', qualname='...', type=, start=1)
- >>> from enum import Flag, auto
- >>> class Color(Flag):
- ... RED = auto()
- ... GREEN = auto()
- ... BLUE = auto()
- >>> purple = Color.RED | Color.BLUE
- >>> white = Color.RED | Color.GREEN | Color.BLUE
- >>> Color.GREEN in purple
- False
- >>> Color.GREEN in white
- True
- >>> purple in white
- True
- >>> white in purple
- False
+:value: What the new Enum class will record as its name.
- .. method:: __iter__(self):
+:names: The Enum members. This can be a whitespace or comma separated string
+ (values will start at 1 unless otherwise specified)::
- Returns all contained members::
+ 'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'
- >>> list(Color.RED)
- [Color.RED]
- >>> list(purple)
- [Color.RED, Color.BLUE]
+ or an iterator of names::
- .. method:: __len__(self):
+ ['RED', 'GREEN', 'BLUE']
- Returns number of members in flag::
+ or an iterator of (name, value) pairs::
- >>> len(Color.GREEN)
- 1
- >>> len(white)
- 3
+ [('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]
- .. method:: __bool__(self):
+ or a mapping::
- Returns *True* if any members in flag, *False* otherwise::
+ {'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}
- >>> bool(Color.GREEN)
- True
- >>> bool(white)
- True
- >>> black = Color(0)
- >>> bool(black)
- False
+:module: name of module where new Enum class can be found.
- .. method:: __or__(self, other)
+:qualname: where in module new Enum class can be found.
- Returns current flag binary or'ed with other::
+:type: type to mix in to new Enum class.
- >>> Color.RED | Color.GREEN
- Color.RED|Color.GREEN
+:start: number to start counting at if only names are passed in.
- .. method:: __and__(self, other)
+.. versionchanged:: 3.5
+ The *start* parameter was added.
- Returns current flag binary and'ed with other::
- >>> purple & white
- Color.RED|Color.BLUE
- >>> purple & Color.GREEN
- 0x0
+Derived Enumerations
+--------------------
- .. method:: __xor__(self, other)
+IntEnum
+^^^^^^^
- Returns current flag binary xor'ed with other::
+The first variation of :class:`Enum` that is provided is also a subclass of
+:class:`int`. Members of an :class:`IntEnum` can be compared to integers;
+by extension, integer enumerations of different types can also be compared
+to each other::
- >>> purple ^ white
- Color.GREEN
- >>> purple ^ Color.GREEN
- Color.RED|Color.GREEN|Color.BLUE
+ >>> from enum import IntEnum
+ >>> class Shape(IntEnum):
+ ... CIRCLE = 1
+ ... SQUARE = 2
+ ...
+ >>> class Request(IntEnum):
+ ... POST = 1
+ ... GET = 2
+ ...
+ >>> Shape == 1
+ False
+ >>> Shape.CIRCLE == 1
+ True
+ >>> Shape.CIRCLE == Request.POST
+ True
- .. method:: __invert__(self):
+However, they still can't be compared to standard :class:`Enum` enumerations::
- Returns all the flags in *type(self)* that are not in self::
+ >>> class Shape(IntEnum):
+ ... CIRCLE = 1
+ ... SQUARE = 2
+ ...
+ >>> class Color(Enum):
+ ... RED = 1
+ ... GREEN = 2
+ ...
+ >>> Shape.CIRCLE == Color.RED
+ False
- >>> ~white
- 0x0
- >>> ~purple
- Color.GREEN
- >>> ~Color.RED
- Color.GREEN|Color.BLUE
+:class:`IntEnum` values behave like integers in other ways you'd expect::
-.. note::
+ >>> int(Shape.CIRCLE)
+ 1
+ >>> ['a', 'b', 'c'][Shape.CIRCLE]
+ 'b'
+ >>> [i for i in range(Shape.SQUARE)]
+ [0, 1]
- Using :class:`auto` with :class:`Flag` results in integers that are powers
- of two, starting with ``1``.
+IntFlag
+^^^^^^^
-.. class:: IntFlag
+The next variation of :class:`Enum` provided, :class:`IntFlag`, is also based
+on :class:`int`. The difference being :class:`IntFlag` members can be combined
+using the bitwise operators (&, \|, ^, ~) and the result is still an
+:class:`IntFlag` member. However, as the name implies, :class:`IntFlag`
+members also subclass :class:`int` and can be used wherever an :class:`int` is
+used. Any operation on an :class:`IntFlag` member besides the bit-wise
+operations will lose the :class:`IntFlag` membership.
- *IntFlag* is the same as *Flag*, but its members are also integers and can be
- used anywhere that an integer can be used.
+.. versionadded:: 3.6
- >>> from enum import IntFlag, auto
- >>> class Color(IntFlag):
- ... RED = auto()
- ... GREEN = auto()
- ... BLUE = auto()
- >>> Color.RED & 2
- 0x0
- >>> Color.RED | 2
- Color.RED|Color.GREEN
+Sample :class:`IntFlag` class::
- If any integer operation is performed with an *IntFlag* member, the result is
- not an *IntFlag*::
+ >>> from enum import IntFlag
+ >>> class Perm(IntFlag):
+ ... R = 4
+ ... W = 2
+ ... X = 1
+ ...
+ >>> Perm.R | Perm.W
+
+ >>> Perm.R + Perm.W
+ 6
+ >>> RW = Perm.R | Perm.W
+ >>> Perm.R in RW
+ True
+
+It is also possible to name the combinations::
+
+ >>> class Perm(IntFlag):
+ ... R = 4
+ ... W = 2
+ ... X = 1
+ ... RWX = 7
+ >>> Perm.RWX
+
+ >>> ~Perm.RWX
+
+
+Another important difference between :class:`IntFlag` and :class:`Enum` is that
+if no flags are set (the value is 0), its boolean evaluation is :data:`False`::
+
+ >>> Perm.R & Perm.X
+
+ >>> bool(Perm.R & Perm.X)
+ False
+
+Because :class:`IntFlag` members are also subclasses of :class:`int` they can
+be combined with them::
+
+ >>> Perm.X | 8
+
+
+
+Flag
+^^^^
+
+The last variation is :class:`Flag`. Like :class:`IntFlag`, :class:`Flag`
+members can be combined using the bitwise operators (&, \|, ^, ~). Unlike
+:class:`IntFlag`, they cannot be combined with, nor compared against, any
+other :class:`Flag` enumeration, nor :class:`int`. While it is possible to
+specify the values directly it is recommended to use :class:`auto` as the
+value and let :class:`Flag` select an appropriate value.
+
+.. versionadded:: 3.6
+
+Like :class:`IntFlag`, if a combination of :class:`Flag` members results in no
+flags being set, the boolean evaluation is :data:`False`::
+
+ >>> from enum import Flag, auto
+ >>> class Color(Flag):
+ ... RED = auto()
+ ... BLUE = auto()
+ ... GREEN = auto()
+ ...
+ >>> Color.RED & Color.GREEN
+
+ >>> bool(Color.RED & Color.GREEN)
+ False
+
+Individual flags should have values that are powers of two (1, 2, 4, 8, ...),
+while combinations of flags won't::
+
+ >>> class Color(Flag):
+ ... RED = auto()
+ ... BLUE = auto()
+ ... GREEN = auto()
+ ... WHITE = RED | BLUE | GREEN
+ ...
+ >>> Color.WHITE
+
+
+Giving a name to the "no flags set" condition does not change its boolean
+value::
+
+ >>> class Color(Flag):
+ ... BLACK = 0
+ ... RED = auto()
+ ... BLUE = auto()
+ ... GREEN = auto()
+ ...
+ >>> Color.BLACK
+
+ >>> bool(Color.BLACK)
+ False
+
+.. note::
- >>> Color.RED + 2
- 3
+ For the majority of new code, :class:`Enum` and :class:`Flag` are strongly
+ recommended, since :class:`IntEnum` and :class:`IntFlag` break some
+ semantic promises of an enumeration (by being comparable to integers, and
+ thus by transitivity to other unrelated enumerations). :class:`IntEnum`
+ and :class:`IntFlag` should be used only in cases where :class:`Enum` and
+ :class:`Flag` will not do; for example, when integer constants are replaced
+ with enumerations, or for interoperability with other systems.
+
+
+Others
+^^^^^^
+
+While :class:`IntEnum` is part of the :mod:`enum` module, it would be very
+simple to implement independently::
+
+ class IntEnum(int, Enum):
+ pass
+
+This demonstrates how similar derived enumerations can be defined; for example
+a :class:`StrEnum` that mixes in :class:`str` instead of :class:`int`.
+
+Some rules:
+
+1. When subclassing :class:`Enum`, mix-in types must appear before
+ :class:`Enum` itself in the sequence of bases, as in the :class:`IntEnum`
+ example above.
+2. While :class:`Enum` can have members of any type, once you mix in an
+ additional type, all the members must have values of that type, e.g.
+ :class:`int` above. This restriction does not apply to mix-ins which only
+ add methods and don't specify another type.
+3. When another data type is mixed in, the :attr:`value` attribute is *not the
+ same* as the enum member itself, although it is equivalent and will compare
+ equal.
+4. %-style formatting: `%s` and `%r` call the :class:`Enum` class's
+ :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as
+ `%i` or `%h` for IntEnum) treat the enum member as its mixed-in type.
+5. :ref:`Formatted string literals `, :meth:`str.format`,
+ and :func:`format` will use the mixed-in type's :meth:`__format__`
+ unless :meth:`__str__` or :meth:`__format__` is overridden in the subclass,
+ in which case the overridden methods or :class:`Enum` methods will be used.
+ Use the !s and !r format codes to force usage of the :class:`Enum` class's
+ :meth:`__str__` and :meth:`__repr__` methods.
+
+When to use :meth:`__new__` vs. :meth:`__init__`
+------------------------------------------------
+
+:meth:`__new__` must be used whenever you want to customize the actual value of
+the :class:`Enum` member. Any other modifications may go in either
+:meth:`__new__` or :meth:`__init__`, with :meth:`__init__` being preferred.
+
+For example, if you want to pass several items to the constructor, but only
+want one of them to be the value::
+
+ >>> class Coordinate(bytes, Enum):
+ ... """
+ ... Coordinate with binary codes that can be indexed by the int code.
+ ... """
+ ... def __new__(cls, value, label, unit):
+ ... obj = bytes.__new__(cls, [value])
+ ... obj._value_ = value
+ ... obj.label = label
+ ... obj.unit = unit
+ ... return obj
+ ... PX = (0, 'P.X', 'km')
+ ... PY = (1, 'P.Y', 'km')
+ ... VX = (2, 'V.X', 'km/s')
+ ... VY = (3, 'V.Y', 'km/s')
+ ...
+
+ >>> print(Coordinate['PY'])
+ Coordinate.PY
+
+ >>> print(Coordinate(3))
+ Coordinate.VY
+
+Interesting examples
+--------------------
+
+While :class:`Enum`, :class:`IntEnum`, :class:`IntFlag`, and :class:`Flag` are
+expected to cover the majority of use-cases, they cannot cover them all. Here
+are recipes for some different types of enumerations that can be used directly,
+or as examples for creating one's own.
+
+
+Omitting values
+^^^^^^^^^^^^^^^
+
+In many use-cases one doesn't care what the actual value of an enumeration
+is. There are several ways to define this type of simple enumeration:
+
+- use instances of :class:`auto` for the value
+- use instances of :class:`object` as the value
+- use a descriptive string as the value
+- use a tuple as the value and a custom :meth:`__new__` to replace the
+ tuple with an :class:`int` value
+
+Using any of these methods signifies to the user that these values are not
+important, and also enables one to add, remove, or reorder members without
+having to renumber the remaining members.
+
+Whichever method you choose, you should provide a :meth:`repr` that also hides
+the (unimportant) value::
+
+ >>> class NoValue(Enum):
+ ... def __repr__(self):
+ ... return '<%s.%s>' % (self.__class__.__name__, self.name)
+ ...
+
+
+Using :class:`auto`
+"""""""""""""""""""
+
+Using :class:`auto` would look like::
+
+ >>> class Color(NoValue):
+ ... RED = auto()
+ ... BLUE = auto()
+ ... GREEN = auto()
+ ...
+ >>> Color.GREEN
+
+
+
+Using :class:`object`
+"""""""""""""""""""""
+
+Using :class:`object` would look like::
+
+ >>> class Color(NoValue):
+ ... RED = object()
+ ... GREEN = object()
+ ... BLUE = object()
+ ...
+ >>> Color.GREEN
+
+
+
+Using a descriptive string
+""""""""""""""""""""""""""
+
+Using a string as the value would look like::
+
+ >>> class Color(NoValue):
+ ... RED = 'stop'
+ ... GREEN = 'go'
+ ... BLUE = 'too fast!'
+ ...
+ >>> Color.GREEN
+
+ >>> Color.GREEN.value
+ 'go'
+
+
+Using a custom :meth:`__new__`
+""""""""""""""""""""""""""""""
+
+Using an auto-numbering :meth:`__new__` would look like::
+
+ >>> class AutoNumber(NoValue):
+ ... def __new__(cls):
+ ... value = len(cls.__members__) + 1
+ ... obj = object.__new__(cls)
+ ... obj._value_ = value
+ ... return obj
+ ...
+ >>> class Color(AutoNumber):
+ ... RED = ()
+ ... GREEN = ()
+ ... BLUE = ()
+ ...
+ >>> Color.GREEN
+
+ >>> Color.GREEN.value
+ 2
+
+To make a more general purpose ``AutoNumber``, add ``*args`` to the signature::
+
+ >>> class AutoNumber(NoValue):
+ ... def __new__(cls, *args): # this is the only change from above
+ ... value = len(cls.__members__) + 1
+ ... obj = object.__new__(cls)
+ ... obj._value_ = value
+ ... return obj
+ ...
+
+Then when you inherit from ``AutoNumber`` you can write your own ``__init__``
+to handle any extra arguments::
+
+ >>> class Swatch(AutoNumber):
+ ... def __init__(self, pantone='unknown'):
+ ... self.pantone = pantone
+ ... AUBURN = '3497'
+ ... SEA_GREEN = '1246'
+ ... BLEACHED_CORAL = () # New color, no Pantone code yet!
+ ...
+ >>> Swatch.SEA_GREEN
+
+ >>> Swatch.SEA_GREEN.pantone
+ '1246'
+ >>> Swatch.BLEACHED_CORAL.pantone
+ 'unknown'
- If a *Flag* operation is performed with an *IntFlag* member and:
+.. note::
- * the result is a valid *IntFlag*: an *IntFlag* is returned
- * the result is not a valid *IntFlag*: the result depends on the *FlagBoundary* setting
+ The :meth:`__new__` method, if defined, is used during creation of the Enum
+ members; it is then replaced by Enum's :meth:`__new__` which is used after
+ class creation for lookup of existing members.
+
+
+OrderedEnum
+^^^^^^^^^^^
+
+An ordered enumeration that is not based on :class:`IntEnum` and so maintains
+the normal :class:`Enum` invariants (such as not being comparable to other
+enumerations)::
+
+ >>> class OrderedEnum(Enum):
+ ... def __ge__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self.value >= other.value
+ ... return NotImplemented
+ ... def __gt__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self.value > other.value
+ ... return NotImplemented
+ ... def __le__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self.value <= other.value
+ ... return NotImplemented
+ ... def __lt__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self.value < other.value
+ ... return NotImplemented
+ ...
+ >>> class Grade(OrderedEnum):
+ ... A = 5
+ ... B = 4
+ ... C = 3
+ ... D = 2
+ ... F = 1
+ ...
+ >>> Grade.C < Grade.A
+ True
+
+
+DuplicateFreeEnum
+^^^^^^^^^^^^^^^^^
+
+Raises an error if a duplicate member name is found instead of creating an
+alias::
+
+ >>> class DuplicateFreeEnum(Enum):
+ ... def __init__(self, *args):
+ ... cls = self.__class__
+ ... if any(self.value == e.value for e in cls):
+ ... a = self.name
+ ... e = cls(self.value).name
+ ... raise ValueError(
+ ... "aliases not allowed in DuplicateFreeEnum: %r --> %r"
+ ... % (a, e))
+ ...
+ >>> class Color(DuplicateFreeEnum):
+ ... RED = 1
+ ... GREEN = 2
+ ... BLUE = 3
+ ... GRENE = 2
+ ...
+ Traceback (most recent call last):
+ ...
+ ValueError: aliases not allowed in DuplicateFreeEnum: 'GRENE' --> 'GREEN'
.. note::
- Using :class:`auto` with :class:`IntFlag` results in integers that are powers
- of two, starting with ``1``.
+ This is a useful example for subclassing Enum to add or change other
+ behaviors as well as disallowing aliases. If the only desired change is
+ disallowing aliases, the :func:`unique` decorator can be used instead.
-.. class:: FlagBoundary
- *FlagBoundary* controls how out-of-range values are handled in *Flag* and its
- subclasses.
+Planet
+^^^^^^
- .. attribute:: STRICT
+If :meth:`__new__` or :meth:`__init__` is defined the value of the enum member
+will be passed to those methods::
+
+ >>> class Planet(Enum):
+ ... MERCURY = (3.303e+23, 2.4397e6)
+ ... VENUS = (4.869e+24, 6.0518e6)
+ ... EARTH = (5.976e+24, 6.37814e6)
+ ... MARS = (6.421e+23, 3.3972e6)
+ ... JUPITER = (1.9e+27, 7.1492e7)
+ ... SATURN = (5.688e+26, 6.0268e7)
+ ... URANUS = (8.686e+25, 2.5559e7)
+ ... NEPTUNE = (1.024e+26, 2.4746e7)
+ ... def __init__(self, mass, radius):
+ ... self.mass = mass # in kilograms
+ ... self.radius = radius # in meters
+ ... @property
+ ... def surface_gravity(self):
+ ... # universal gravitational constant (m3 kg-1 s-2)
+ ... G = 6.67300E-11
+ ... return G * self.mass / (self.radius * self.radius)
+ ...
+ >>> Planet.EARTH.value
+ (5.976e+24, 6378140.0)
+ >>> Planet.EARTH.surface_gravity
+ 9.802652743337129
+
+
+TimePeriod
+^^^^^^^^^^
+
+An example to show the :attr:`_ignore_` attribute in use::
+
+ >>> from datetime import timedelta
+ >>> class Period(timedelta, Enum):
+ ... "different lengths of time"
+ ... _ignore_ = 'Period i'
+ ... Period = vars()
+ ... for i in range(367):
+ ... Period['day_%d' % i] = i
+ ...
+ >>> list(Period)[:2]
+ [, ]
+ >>> list(Period)[-2:]
+ [, ]
+
+
+How are Enums different?
+------------------------
+
+Enums have a custom metaclass that affects many aspects of both derived Enum
+classes and their instances (members).
+
+
+Enum Classes
+^^^^^^^^^^^^
+
+The :class:`EnumMeta` metaclass is responsible for providing the
+:meth:`__contains__`, :meth:`__dir__`, :meth:`__iter__` and other methods that
+allow one to do things with an :class:`Enum` class that fail on a typical
+class, such as `list(Color)` or `some_enum_var in Color`. :class:`EnumMeta` is
+responsible for ensuring that various other methods on the final :class:`Enum`
+class are correct (such as :meth:`__new__`, :meth:`__getnewargs__`,
+:meth:`__str__` and :meth:`__repr__`).
+
+
+Enum Members (aka instances)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The most interesting thing about Enum members is that they are singletons.
+:class:`EnumMeta` creates them all while it is creating the :class:`Enum`
+class itself, and then puts a custom :meth:`__new__` in place to ensure
+that no new ones are ever instantiated by returning only the existing
+member instances.
+
+
+Finer Points
+^^^^^^^^^^^^
+
+Supported ``__dunder__`` names
+""""""""""""""""""""""""""""""
+
+:attr:`__members__` is a read-only ordered mapping of ``member_name``:``member``
+items. It is only available on the class.
+
+:meth:`__new__`, if specified, must create and return the enum members; it is
+also a very good idea to set the member's :attr:`_value_` appropriately. Once
+all the members are created it is no longer used.
+
+
+Supported ``_sunder_`` names
+""""""""""""""""""""""""""""
+
+- ``_name_`` -- name of the member
+- ``_value_`` -- value of the member; can be set / modified in ``__new__``
+
+- ``_missing_`` -- a lookup function used when a value is not found; may be
+ overridden
+- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`,
+ that will not be transformed into members, and will be removed from the final
+ class
+- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent
+ (class attribute, removed during class creation)
+- ``_generate_next_value_`` -- used by the `Functional API`_ and by
+ :class:`auto` to get an appropriate value for an enum member; may be
+ overridden
+
+.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_``
+.. versionadded:: 3.7 ``_ignore_``
+
+To help keep Python 2 / Python 3 code in sync an :attr:`_order_` attribute can
+be provided. It will be checked against the actual order of the enumeration
+and raise an error if the two do not match::
+
+ >>> class Color(Enum):
+ ... _order_ = 'RED GREEN BLUE'
+ ... RED = 1
+ ... BLUE = 3
+ ... GREEN = 2
+ ...
+ Traceback (most recent call last):
+ ...
+ TypeError: member order does not match _order_
- Out-of-range values cause a :exc:`ValueError` to be raised. This is the
- default for :class:`Flag`::
+.. note::
- >>> from enum import Flag, STRICT
- >>> class StrictFlag(Flag, boundary=STRICT):
- ... RED = auto()
- ... GREEN = auto()
- ... BLUE = auto()
- >>> StrictFlag(2**2 + 2**4)
- Traceback (most recent call last):
- ...
- ValueError: StrictFlag: invalid value: 20
- given 0b0 10100
- allowed 0b0 00111
+ In Python 2 code the :attr:`_order_` attribute is necessary as definition
+ order is lost before it can be recorded.
- .. attribute:: CONFORM
- Out-of-range values have invalid values removed, leaving a valid *Flag*
- value::
+_Private__names
+"""""""""""""""
- >>> from enum import Flag, CONFORM
- >>> class ConformFlag(Flag, boundary=CONFORM):
- ... RED = auto()
- ... GREEN = auto()
- ... BLUE = auto()
- >>> ConformFlag(2**2 + 2**4)
- ConformFlag.BLUE
+:ref:`Private names ` will be normal attributes in Python
+3.11 instead of either an error or a member (depending on if the name ends with
+an underscore). Using these names in 3.10 will issue a :exc:`DeprecationWarning`.
- .. attribute:: EJECT
- Out-of-range values lose their *Flag* membership and revert to :class:`int`.
- This is the default for :class:`IntFlag`::
+``Enum`` member type
+""""""""""""""""""""
- >>> from enum import Flag, EJECT
- >>> class EjectFlag(Flag, boundary=EJECT):
- ... RED = auto()
- ... GREEN = auto()
- ... BLUE = auto()
- >>> EjectFlag(2**2 + 2**4)
- 20
+:class:`Enum` members are instances of their :class:`Enum` class, and are
+normally accessed as ``EnumClass.member``. Under certain circumstances they
+can also be accessed as ``EnumClass.member.member``, but you should never do
+this as that lookup may fail or, worse, return something besides the
+:class:`Enum` member you are looking for (this is another good reason to use
+all-uppercase names for members)::
- .. attribute:: KEEP
+ >>> class FieldTypes(Enum):
+ ... name = 0
+ ... value = 1
+ ... size = 2
+ ...
+ >>> FieldTypes.value.size
+
+ >>> FieldTypes.size.value
+ 2
- Out-of-range values are kept, and the *Flag* membership is kept. This is
- used for some stdlib flags:
+.. note::
- >>> from enum import Flag, KEEP
- >>> class KeepFlag(Flag, boundary=KEEP):
- ... RED = auto()
- ... GREEN = auto()
- ... BLUE = auto()
- >>> KeepFlag(2**2 + 2**4)
- KeepFlag.BLUE|0x10
+ This behavior is deprecated and will be removed in 3.11.
+.. versionchanged:: 3.5
-Utilites and Decorators
------------------------
-.. class:: auto
+Boolean value of ``Enum`` classes and members
+"""""""""""""""""""""""""""""""""""""""""""""
- *auto* can be used in place of a value. If used, the *Enum* machinery will
- call an *Enum*'s :meth:`_generate_next_value_` to get an appropriate value.
- For *Enum* and *IntEnum* that appropriate value will be the last value plus
- one; for *Flag* and *IntFlag* it will be the first power-of-two greater
- than the last value; for *StrEnum* it will be the lower-cased version of the
- member's name.
+:class:`Enum` members that are mixed with non-:class:`Enum` types (such as
+:class:`int`, :class:`str`, etc.) are evaluated according to the mixed-in
+type's rules; otherwise, all members evaluate as :data:`True`. To make your
+own Enum's boolean evaluation depend on the member's value add the following to
+your class::
- ``_generate_next_value_`` can be overridden to customize the values used by
- *auto*.
+ def __bool__(self):
+ return bool(self.value)
-.. decorator:: global_enum
+:class:`Enum` classes always evaluate as :data:`True`.
- A :keyword:`class` decorator specifically for enumerations. It replaces the
- :meth:`__repr__` method with one that shows *module_name*.*member_name*. It
- also injects the members, and their aliases, into the the global namespace
- they were defined in.
+``Enum`` classes with methods
+"""""""""""""""""""""""""""""
-.. decorator:: property
+If you give your :class:`Enum` subclass extra methods, like the `Planet`_
+class above, those methods will show up in a :func:`dir` of the member,
+but not of the class::
- A decorator similar to the built-in *property*, but specifically for
- enumerations. It allows member attributes to have the same names as members
- themselves.
+ >>> dir(Planet)
+ ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS', 'VENUS', '__class__', '__doc__', '__members__', '__module__']
+ >>> dir(Planet.EARTH)
+ ['__class__', '__doc__', '__module__', 'mass', 'name', 'radius', 'surface_gravity', 'value']
- .. 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``.
-.. decorator:: unique
+Combining members of ``Flag``
+"""""""""""""""""""""""""""""
+
+If a combination of Flag members is not named, the :func:`repr` will include
+all named flags and all named combinations of flags that are in the value::
+
+ >>> class Color(Flag):
+ ... RED = auto()
+ ... GREEN = auto()
+ ... BLUE = auto()
+ ... MAGENTA = RED | BLUE
+ ... YELLOW = RED | GREEN
+ ... CYAN = GREEN | BLUE
+ ...
+ >>> Color(3) # named combination
+
+ >>> Color(7) # not named combination
+
+
+.. note::
+
+ In 3.11 unnamed combinations of flags will only produce the canonical flag
+ members (aka single-value flags). So ``Color(7)`` will produce something
+ like ````.
- A :keyword:`class` decorator specifically for enumerations. It searches an
- enumeration's :attr:`__members__`, gathering any aliases it finds; if any are
- found :exc:`ValueError` is raised with the details::
-
- >>> from enum import Enum, unique
- >>> @unique
- ... class Mistake(Enum):
- ... ONE = 1
- ... TWO = 2
- ... THREE = 3
- ... FOUR = 3
- ...
- Traceback (most recent call last):
- ...
- ValueError: duplicate values found in : FOUR -> THREE
diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst
index 1cbd51c582c0cf..c87da091bf84f6 100644
--- a/Doc/library/errno.rst
+++ b/Doc/library/errno.rst
@@ -8,7 +8,7 @@
This module makes available standard ``errno`` system symbols. The value of each
symbol is the corresponding integer value. The names and descriptions are
-borrowed from :file:`linux/include/errno.h`, which should be pretty
+borrowed from :file:`linux/include/errno.h`, which should be
all-inclusive.
@@ -27,25 +27,26 @@ defined by the module. The specific list of defined symbols is available as
.. data:: EPERM
- Operation not permitted
+ Operation not permitted. This error is mapped to the exception
+ :exc:`PermissionError`.
.. data:: ENOENT
- No such file or directory
+ No such file or directory. This error is mapped to the exception
+ :exc:`FileNotFoundError`.
.. data:: ESRCH
- No such process
+ No such process. This error is mapped to the exception
+ :exc:`ProcessLookupError`.
.. data:: EINTR
- Interrupted system call.
-
- .. seealso::
- This error is mapped to the exception :exc:`InterruptedError`.
+ Interrupted system call. This error is mapped to the exception
+ :exc:`InterruptedError`.
.. data:: EIO
@@ -75,12 +76,13 @@ defined by the module. The specific list of defined symbols is available as
.. data:: ECHILD
- No child processes
+ No child processes. This error is mapped to the exception
+ :exc:`ChildProcessError`.
.. data:: EAGAIN
- Try again
+ Try again. This error is mapped to the exception :exc:`BlockingIOError`.
.. data:: ENOMEM
@@ -90,7 +92,8 @@ defined by the module. The specific list of defined symbols is available as
.. data:: EACCES
- Permission denied
+ Permission denied. This error is mapped to the exception
+ :exc:`PermissionError`.
.. data:: EFAULT
@@ -110,7 +113,8 @@ defined by the module. The specific list of defined symbols is available as
.. data:: EEXIST
- File exists
+ File exists. This error is mapped to the exception
+ :exc:`FileExistsError`.
.. data:: EXDEV
@@ -125,12 +129,14 @@ defined by the module. The specific list of defined symbols is available as
.. data:: ENOTDIR
- Not a directory
+ Not a directory. This error is mapped to the exception
+ :exc:`NotADirectoryError`.
.. data:: EISDIR
- Is a directory
+ Is a directory. This error is mapped to the exception
+ :exc:`IsADirectoryError`.
.. data:: EINVAL
@@ -185,7 +191,8 @@ defined by the module. The specific list of defined symbols is available as
.. data:: EPIPE
- Broken pipe
+ Broken pipe. This error is mapped to the exception
+ :exc:`BrokenPipeError`.
.. data:: EDOM
@@ -230,7 +237,8 @@ defined by the module. The specific list of defined symbols is available as
.. data:: EWOULDBLOCK
- Operation would block
+ Operation would block. This error is mapped to the exception
+ :exc:`BlockingIOError`.
.. data:: ENOMSG
@@ -540,12 +548,14 @@ defined by the module. The specific list of defined symbols is available as
.. data:: ECONNABORTED
- Software caused connection abort
+ Software caused connection abort. This error is mapped to the
+ exception :exc:`ConnectionAbortedError`.
.. data:: ECONNRESET
- Connection reset by peer
+ Connection reset by peer. This error is mapped to the exception
+ :exc:`ConnectionResetError`.
.. data:: ENOBUFS
@@ -565,7 +575,8 @@ defined by the module. The specific list of defined symbols is available as
.. data:: ESHUTDOWN
- Cannot send after transport endpoint shutdown
+ Cannot send after transport endpoint shutdown. This error is mapped
+ to the exception :exc:`BrokenPipeError`.
.. data:: ETOOMANYREFS
@@ -575,12 +586,14 @@ defined by the module. The specific list of defined symbols is available as
.. data:: ETIMEDOUT
- Connection timed out
+ Connection timed out. This error is mapped to the exception
+ :exc:`TimeoutError`.
.. data:: ECONNREFUSED
- Connection refused
+ Connection refused. This error is mapped to the exception
+ :exc:`ConnectionRefusedError`.
.. data:: EHOSTDOWN
@@ -595,12 +608,14 @@ defined by the module. The specific list of defined symbols is available as
.. data:: EALREADY
- Operation already in progress
+ Operation already in progress. This error is mapped to the
+ exception :exc:`BlockingIOError`.
.. data:: EINPROGRESS
- Operation now in progress
+ Operation now in progress. This error is mapped to the exception
+ :exc:`BlockingIOError`.
.. data:: ESTALE
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index c83daae302c19d..9a3c92554df632 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -34,15 +34,18 @@ class or one of its subclasses, and not from :exc:`BaseException`. More
information on defining exceptions is available in the Python Tutorial under
:ref:`tut-userexceptions`.
-When raising (or re-raising) an exception in an :keyword:`except` or
-:keyword:`finally` clause
-:attr:`__context__` is automatically set to the last exception caught; if the
-new exception is not handled the traceback that is eventually displayed will
-include the originating exception(s) and the final exception.
-
-When raising a new exception (rather than using a bare ``raise`` to re-raise
-the exception currently being handled), the implicit exception context can be
-supplemented with an explicit cause by using :keyword:`from` with
+
+Exception context
+-----------------
+
+When raising a new exception while another exception
+is already being handled, the new exception's
+:attr:`__context__` attribute is automatically set to the handled
+exception. An exception may be handled when an :keyword:`except` or
+:keyword:`finally` clause, or a :keyword:`with` statement, is used.
+
+This implicit exception context can be
+supplemented with an explicit cause by using :keyword:`!from` with
:keyword:`raise`::
raise new_exc from original_exc
@@ -67,6 +70,25 @@ exceptions so that the final line of the traceback always shows the last
exception that was raised.
+Inheriting from built-in exceptions
+-----------------------------------
+
+User code can create subclasses that inherit from an exception type.
+It's recommended to only subclass one exception type at a time to avoid
+any possible conflicts between how the bases handle the ``args``
+attribute, as well as due to possible memory layout incompatibilities.
+
+.. impl-detail::
+
+ Most built-in exceptions are implemented in C for efficiency, see:
+ :source:`Objects/exceptions.c`. Some have custom memory layouts
+ which makes it impossible to create a subclass that inherits from
+ multiple exception types. The memory layout of a type is an implementation
+ detail and might change between Python versions, leading to new
+ conflicts in the future. Therefore, it's recommended to avoid
+ subclassing multiple exception types altogether.
+
+
Base classes
------------
@@ -96,7 +118,7 @@ The following exceptions are used mostly as base classes for other exceptions.
instance of ``OtherException`` while preserving the traceback. Once
raised, the current frame is pushed onto the traceback of the
``OtherException``, as would have happened to the traceback of the
- original ``SomeException`` had we allowed it to propagate to the caller.
+ original ``SomeException`` had we allowed it to propagate to the caller. ::
try:
...
@@ -224,6 +246,15 @@ The following exceptions are the exceptions that are usually raised.
accidentally caught by code that catches :exc:`Exception` and thus prevent
the interpreter from exiting.
+ .. note::
+
+ Catching a :exc:`KeyboardInterrupt` requires special consideration.
+ Because it can be raised at unpredictable points, it may, in some
+ circumstances, leave the running program in an inconsistent state. It is
+ generally best to allow :exc:`KeyboardInterrupt` to end the program as
+ quickly as possible or avoid raising it entirely. (See
+ :ref:`handlers-and-exceptions`.)
+
.. exception:: MemoryError
@@ -409,14 +440,16 @@ The following exceptions are the exceptions that are usually raised.
.. versionadded:: 3.5
-.. exception:: SyntaxError
+.. exception:: SyntaxError(message, details)
Raised when the parser encounters a syntax error. This may occur in an
- :keyword:`import` statement, in a call to the built-in functions :func:`exec`
+ :keyword:`import` statement, in a call to the built-in functions
+ :func:`compile`, :func:`exec`,
or :func:`eval`, or when reading the initial script or standard input
(also interactively).
The :func:`str` of the exception instance returns only the error message.
+ Details is a tuple whose members are also available as separate attributes.
.. attribute:: filename
@@ -446,6 +479,11 @@ The following exceptions are the exceptions that are usually raised.
The column in the end line where the error occurred finishes. This is
1-indexed: the first character in the line has an ``offset`` of 1.
+ For errors in f-string fields, the message is prefixed by "f-string: "
+ and the offsets are offsets in a text constructed from the replacement
+ expression. For example, compiling f'Bad {a b} field' results in this
+ args attribute: ('f-string: ...', ('', 1, 2, '(a b)\n', 1, 5)).
+
.. versionchanged:: 3.10
Added the :attr:`end_lineno` and :attr:`end_offset` attributes.
@@ -606,8 +644,8 @@ depending on the system error code.
Raised when an operation would block on an object (e.g. socket) set
for non-blocking operation.
- Corresponds to :c:data:`errno` ``EAGAIN``, ``EALREADY``,
- ``EWOULDBLOCK`` and ``EINPROGRESS``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.EAGAIN`, :py:data:`~errno.EALREADY`,
+ :py:data:`~errno.EWOULDBLOCK` and :py:data:`~errno.EINPROGRESS`.
In addition to those of :exc:`OSError`, :exc:`BlockingIOError` can have
one more attribute:
@@ -621,7 +659,7 @@ depending on the system error code.
.. exception:: ChildProcessError
Raised when an operation on a child process failed.
- Corresponds to :c:data:`errno` ``ECHILD``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ECHILD`.
.. exception:: ConnectionError
@@ -635,35 +673,35 @@ depending on the system error code.
A subclass of :exc:`ConnectionError`, raised when trying to write on a
pipe while the other end has been closed, or trying to write on a socket
which has been shutdown for writing.
- Corresponds to :c:data:`errno` ``EPIPE`` and ``ESHUTDOWN``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.EPIPE` and :py:data:`~errno.ESHUTDOWN`.
.. exception:: ConnectionAbortedError
A subclass of :exc:`ConnectionError`, raised when a connection attempt
is aborted by the peer.
- Corresponds to :c:data:`errno` ``ECONNABORTED``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ECONNABORTED`.
.. exception:: ConnectionRefusedError
A subclass of :exc:`ConnectionError`, raised when a connection attempt
is refused by the peer.
- Corresponds to :c:data:`errno` ``ECONNREFUSED``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ECONNREFUSED`.
.. exception:: ConnectionResetError
A subclass of :exc:`ConnectionError`, raised when a connection is
reset by the peer.
- Corresponds to :c:data:`errno` ``ECONNRESET``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ECONNRESET`.
.. exception:: FileExistsError
Raised when trying to create a file or directory which already exists.
- Corresponds to :c:data:`errno` ``EEXIST``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.EEXIST`.
.. exception:: FileNotFoundError
Raised when a file or directory is requested but doesn't exist.
- Corresponds to :c:data:`errno` ``ENOENT``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ENOENT`.
.. exception:: InterruptedError
@@ -679,29 +717,31 @@ depending on the system error code.
Raised when a file operation (such as :func:`os.remove`) is requested
on a directory.
- Corresponds to :c:data:`errno` ``EISDIR``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.EISDIR`.
.. exception:: NotADirectoryError
- Raised when a directory operation (such as :func:`os.listdir`) is requested
- on something which is not a directory.
- Corresponds to :c:data:`errno` ``ENOTDIR``.
+ Raised when a directory operation (such as :func:`os.listdir`) is requested on
+ something which is not a directory. On most POSIX platforms, it may also be
+ raised if an operation attempts to open or traverse a non-directory file as if
+ it were a directory.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ENOTDIR`.
.. exception:: PermissionError
Raised when trying to run an operation without the adequate access
rights - for example filesystem permissions.
- Corresponds to :c:data:`errno` ``EACCES`` and ``EPERM``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.EACCES` and :py:data:`~errno.EPERM`.
.. exception:: ProcessLookupError
Raised when a given process doesn't exist.
- Corresponds to :c:data:`errno` ``ESRCH``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ESRCH`.
.. exception:: TimeoutError
Raised when a system function timed out at the system level.
- Corresponds to :c:data:`errno` ``ETIMEDOUT``.
+ Corresponds to :c:data:`errno` :py:data:`~errno.ETIMEDOUT`.
.. versionadded:: 3.3
All the above :exc:`OSError` subclasses were added.
@@ -739,6 +779,8 @@ The following exceptions are used as warning categories; see the
(:pep:`565`). Enabling the :ref:`Python Development Mode ` shows
this warning.
+ The deprecation policy is described in :pep:`387`.
+
.. exception:: PendingDeprecationWarning
@@ -753,6 +795,8 @@ The following exceptions are used as warning categories; see the
Ignored by the default warning filters. Enabling the :ref:`Python
Development Mode ` shows this warning.
+ The deprecation policy is described in :pep:`387`.
+
.. exception:: SyntaxWarning
diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst
index 59274c1dd7ec35..be0912376bd8ef 100644
--- a/Doc/library/faulthandler.rst
+++ b/Doc/library/faulthandler.rst
@@ -76,6 +76,10 @@ Fault handler state
.. versionchanged:: 3.6
On Windows, a handler for Windows exception is also installed.
+ .. versionchanged:: 3.10
+ The dump now mentions if a garbage collector collection is running
+ if *all_threads* is true.
+
.. function:: disable()
Disable the fault handler: uninstall the signal handlers installed by
diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst
index 9d8021150c42f5..d9b579fc47d3d8 100644
--- a/Doc/library/fcntl.rst
+++ b/Doc/library/fcntl.rst
@@ -37,7 +37,8 @@ descriptor.
On macOS, the fcntl module exposes the ``F_GETPATH`` constant, which obtains
the path of a file from a file descriptor.
On Linux(>=3.15), the fcntl module exposes the ``F_OFD_GETLK``, ``F_OFD_SETLK``
- and ``F_OFD_SETLKW`` constants, which working with open file description locks.
+ and ``F_OFD_SETLKW`` constants, which are used when working with open file
+ description locks.
.. versionchanged:: 3.10
On Linux >= 2.6.11, the fcntl module exposes the ``F_GETPIPE_SZ`` and
diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst
index c60603b30a6d7d..83e9e14ddcacd8 100644
--- a/Doc/library/filecmp.rst
+++ b/Doc/library/filecmp.rst
@@ -22,8 +22,11 @@ The :mod:`filecmp` module defines the following functions:
Compare the files named *f1* and *f2*, returning ``True`` if they seem equal,
``False`` otherwise.
- If *shallow* is true, files with identical :func:`os.stat` signatures are
- taken to be equal. Otherwise, the contents of the files are compared.
+ If *shallow* is true and the :func:`os.stat` signatures (file type, size, and
+ modification time) of both files are identical, the files are taken to be
+ equal.
+
+ Otherwise, the files are treated as different if their sizes or contents differ.
Note that no external programs are called from this function, giving it
portability and efficiency.
diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst
index e9c2e1fbbdf3e8..7b33b3364572d9 100644
--- a/Doc/library/fileformats.rst
+++ b/Doc/library/fileformats.rst
@@ -13,5 +13,4 @@ that aren't markup languages and are not related to e-mail.
csv.rst
configparser.rst
netrc.rst
- xdrlib.rst
plistlib.rst
diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst
index 819640045cadf7..2df895a69c43dd 100644
--- a/Doc/library/fileinput.rst
+++ b/Doc/library/fileinput.rst
@@ -50,8 +50,8 @@ You can control how files are opened by providing an opening hook via the
*openhook* parameter to :func:`fileinput.input` or :class:`FileInput()`. The
hook must be a function that takes two arguments, *filename* and *mode*, and
returns an accordingly opened file-like object. If *encoding* and/or *errors*
-are specified, they will be passed to the hook as aditional keyword arguments.
-This module provides a :func:`hook_encoded` to support compressed files.
+are specified, they will be passed to the hook as additional keyword arguments.
+This module provides a :func:`hook_compressed` to support compressed files.
The following function is the primary interface of this module:
@@ -205,7 +205,7 @@ The two following opening hooks are provided by this module:
modules. If the filename extension is not ``'.gz'`` or ``'.bz2'``, the file is
opened normally (ie, using :func:`open` without any decompression).
- The *encoding* and *errors* values are passed to to :class:`io.TextIOWrapper`
+ The *encoding* and *errors* values are passed to :class:`io.TextIOWrapper`
for compressed files and open for normal files.
Usage example: ``fi = fileinput.FileInput(openhook=fileinput.hook_compressed, encoding="utf-8")``
@@ -227,5 +227,5 @@ The two following opening hooks are provided by this module:
Added the optional *errors* parameter.
.. deprecated:: 3.10
- This function is deprecated since :func:`input` and :class:`FileInput`
+ This function is deprecated since :func:`fileinput.input` and :class:`FileInput`
now have *encoding* and *errors* parameters.
diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst
index a4d006eb58ffeb..0f7940ae68bef4 100644
--- a/Doc/library/fractions.rst
+++ b/Doc/library/fractions.rst
@@ -105,10 +105,10 @@ another rational number, or from a string.
.. versionadded:: 3.8
- .. method:: from_float(flt)
+ .. classmethod:: from_float(flt)
- This class method constructs a :class:`Fraction` representing the exact
- value of *flt*, which must be a :class:`float`. Beware that
+ Alternative constructor which only accepts instances of
+ :class:`float` or :class:`numbers.Integral`. Beware that
``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)``.
.. note::
@@ -117,10 +117,10 @@ another rational number, or from a string.
:class:`Fraction` instance directly from a :class:`float`.
- .. method:: from_decimal(dec)
+ .. classmethod:: from_decimal(dec)
- This class method constructs a :class:`Fraction` representing the exact
- value of *dec*, which must be a :class:`decimal.Decimal` instance.
+ Alternative constructor which only accepts instances of
+ :class:`decimal.Decimal` or :class:`numbers.Integral`.
.. note::
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index f4d4cdf9ada9d9..2f94ac499285db 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -17,7 +17,7 @@ This module defines the class :class:`FTP` and a few related items. The
this to write Python programs that perform a variety of automated FTP jobs, such
as mirroring other FTP servers. It is also used by the module
:mod:`urllib.request` to handle URLs that use FTP. For more information on FTP
-(File Transfer Protocol), see Internet :rfc:`959`.
+(File Transfer Protocol), see internet :rfc:`959`.
The default encoding is UTF-8, following :rfc:`2640`.
@@ -28,6 +28,7 @@ Here's a sample session using the :mod:`ftplib` module::
>>> ftp.login() # user anonymous, passwd anonymous@
'230 Login successful.'
>>> ftp.cwd('debian') # change into "debian" directory
+ '250 Directory successfully changed.'
>>> ftp.retrlines('LIST') # list directory contents
-rw-rw-r-- 1 1176 1176 1063 Jun 15 10:18 README
...
@@ -39,6 +40,7 @@ Here's a sample session using the :mod:`ftplib` module::
>>> ftp.retrbinary('RETR README', fp.write)
'226 Transfer complete.'
>>> ftp.quit()
+ '221 Goodbye.'
The module defines the following items:
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 7d8a669f9e16d4..d22cc2812dce44 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -66,9 +66,6 @@ are always available. They are listed here in alphabetical order.
Return an :term:`asynchronous iterator` for an :term:`asynchronous iterable`.
Equivalent to calling ``x.__aiter__()``.
- ``aiter(x)`` itself has an ``__aiter__()`` method that returns ``x``,
- so ``aiter(aiter(x))`` is the same as ``aiter(x)``.
-
Note: Unlike :func:`iter`, :func:`aiter` has no 2-argument variant.
.. versionadded:: 3.10
@@ -116,7 +113,7 @@ are always available. They are listed here in alphabetical order.
As :func:`repr`, return a string containing a printable representation of an
object, but escape the non-ASCII characters in the string returned by
- :func:`repr` using ``\x``, ``\u`` or ``\U`` escapes. This generates a string
+ :func:`repr` using ``\x``, ``\u``, or ``\U`` escapes. This generates a string
similar to that returned by :func:`repr` in Python 2.
@@ -132,7 +129,7 @@ are always available. They are listed here in alphabetical order.
>>> bin(-10)
'-0b1010'
- If prefix "0b" is desired or not, you can use either of the following ways.
+ If the prefix "0b" is desired or not, you can use either of the following ways.
>>> format(14, '#b'), format(14, 'b')
('0b1110', '1110')
@@ -146,7 +143,7 @@ are always available. They are listed here in alphabetical order.
Return a Boolean value, i.e. one of ``True`` or ``False``. *x* is converted
using the standard :ref:`truth testing procedure `. If *x* is false
- or omitted, this returns ``False``; otherwise it returns ``True``. The
+ or omitted, this returns ``False``; otherwise, it returns ``True``. The
:class:`bool` class is a subclass of :class:`int` (see :ref:`typesnumeric`).
It cannot be subclassed further. Its only instances are ``False`` and
``True`` (see :ref:`bltin-boolean-values`).
@@ -206,7 +203,7 @@ are always available. They are listed here in alphabetical order.
.. class:: bytes([source[, encoding[, errors]]])
:noindex:
- Return a new "bytes" object, which is an immutable sequence of integers in
+ Return a new "bytes" object which is an immutable sequence of integers in
the range ``0 <= x < 256``. :class:`bytes` is an immutable version of
:class:`bytearray` -- it has the same non-mutating methods and the same
indexing and slicing behavior.
@@ -245,13 +242,13 @@ are always available. They are listed here in alphabetical order.
Transform a method into a class method.
- A class method receives the class as implicit first argument, just like an
+ A class method receives the class as an implicit first argument, just like an
instance method receives the instance. To declare a class method, use this
idiom::
class C:
@classmethod
- def f(cls, arg1, arg2, ...): ...
+ def f(cls, arg1, arg2): ...
The ``@classmethod`` form is a function :term:`decorator` -- see
:ref:`function` for details.
@@ -342,7 +339,7 @@ are always available. They are listed here in alphabetical order.
object due to stack depth limitations in Python's AST compiler.
.. versionchanged:: 3.2
- Allowed use of Windows and Mac newlines. Also input in ``'exec'`` mode
+ Allowed use of Windows and Mac newlines. Also, input in ``'exec'`` mode
does not have to end in a newline anymore. Added the *optimize* parameter.
.. versionchanged:: 3.5
@@ -420,7 +417,7 @@ are always available. They are listed here in alphabetical order.
If the object does not provide :meth:`__dir__`, the function tries its best to
gather information from the object's :attr:`~object.__dict__` attribute, if defined, and
- from its type object. The resulting list is not necessarily complete, and may
+ from its type object. The resulting list is not necessarily complete and may
be inaccurate when the object has a custom :func:`__getattr__`.
The default :func:`dir` mechanism behaves differently with different types of
@@ -466,7 +463,7 @@ are always available. They are listed here in alphabetical order.
.. function:: divmod(a, b)
- Take two (non complex) numbers as arguments and return a pair of numbers
+ Take two (non-complex) numbers as arguments and return a pair of numbers
consisting of their quotient and remainder when using integer division. With
mixed operand types, the rules for binary arithmetic operators apply. For
integers, the result is the same as ``(a // b, a % b)``. For floating point
@@ -528,13 +525,13 @@ are always available. They are listed here in alphabetical order.
2
This function can also be used to execute arbitrary code objects (such as
- those created by :func:`compile`). In this case pass a code object instead
+ those created by :func:`compile`). In this case, pass a code object instead
of a string. If the code object has been compiled with ``'exec'`` as the
*mode* argument, :func:`eval`\'s return value will be ``None``.
Hints: dynamic execution of statements is supported by the :func:`exec`
function. The :func:`globals` and :func:`locals` functions
- returns the current global and local dictionary, respectively, which may be
+ return the current global and local dictionary, respectively, which may be
useful to pass around for use by :func:`eval` or :func:`exec`.
If the given source is a string, then leading and trailing spaces and tabs
@@ -557,7 +554,7 @@ are always available. They are listed here in alphabetical order.
a suite of Python statements which is then executed (unless a syntax error
occurs). [#]_ If it is a code object, it is simply executed. In all cases,
the code that's executed is expected to be valid as file input (see the
- section "File input" in the Reference Manual). Be aware that the
+ section :ref:`file-input` in the Reference Manual). Be aware that the
:keyword:`nonlocal`, :keyword:`yield`, and :keyword:`return`
statements may not be used outside of
function definitions even within the context of code passed to the
@@ -569,7 +566,7 @@ are always available. They are listed here in alphabetical order.
will be used for both the global and the local variables. If *globals* and
*locals* are given, they are used for the global and local variables,
respectively. If provided, *locals* can be any mapping object. Remember
- that at module level, globals and locals are the same dictionary. If exec
+ that at the module level, globals and locals are the same dictionary. If exec
gets two separate objects as *globals* and *locals*, the code will be
executed as if it were embedded in a class definition.
@@ -627,7 +624,7 @@ are always available. They are listed here in alphabetical order.
preceded by a sign, and optionally embedded in whitespace. The optional
sign may be ``'+'`` or ``'-'``; a ``'+'`` sign has no effect on the value
produced. The argument may also be a string representing a NaN
- (not-a-number), or a positive or negative infinity. More precisely, the
+ (not-a-number), or positive or negative infinity. More precisely, the
input must conform to the following grammar after leading and trailing
whitespace characters are removed:
@@ -640,7 +637,7 @@ are always available. They are listed here in alphabetical order.
Here ``floatnumber`` is the form of a Python floating-point literal,
described in :ref:`floating`. Case is not significant, so, for example,
- "inf", "Inf", "INFINITY" and "iNfINity" are all acceptable spellings for
+ "inf", "Inf", "INFINITY", and "iNfINity" are all acceptable spellings for
positive infinity.
Otherwise, if the argument is an integer or a floating point number, a
@@ -687,7 +684,7 @@ are always available. They are listed here in alphabetical order.
Convert a *value* to a "formatted" representation, as controlled by
*format_spec*. The interpretation of *format_spec* will depend on the type
- of the *value* argument, however there is a standard formatting syntax that
+ of the *value* argument; however, there is a standard formatting syntax that
is used by most built-in types: :ref:`formatspec`.
The default *format_spec* is an empty string which usually gives the same
@@ -736,9 +733,9 @@ are always available. They are listed here in alphabetical order.
.. function:: globals()
- Return a dictionary representing the current global symbol table. This is always
- the dictionary of the current module (inside a function or method, this is the
- module where it is defined, not the module from which it is called).
+ Return the dictionary implementing the current module namespace. For code within
+ functions, this is set when the function is defined and remains the same
+ regardless of where the function is called.
.. function:: hasattr(object, name)
@@ -771,7 +768,7 @@ are always available. They are listed here in alphabetical order.
topic, and a help page is printed on the console. If the argument is any other
kind of object, a help page on the object is generated.
- Note that if a slash(/) appears in the parameter list of a function, when
+ Note that if a slash(/) appears in the parameter list of a function when
invoking :func:`help`, it means that the parameters prior to the slash are
positional-only. For more info, see
:ref:`the FAQ entry on positional-only parameters `.
@@ -849,8 +846,8 @@ are always available. They are listed here in alphabetical order.
.. audit-event:: builtins.input/result result input
- Raises an auditing event ``builtins.input/result`` with the result after
- successfully reading input.
+ Raises an :ref:`auditing event ` ``builtins.input/result``
+ with the result after successfully reading input.
.. class:: int([x])
@@ -898,7 +895,7 @@ are always available. They are listed here in alphabetical order.
.. function:: isinstance(object, classinfo)
Return ``True`` if the *object* argument is an instance of the *classinfo*
- argument, or of a (direct, indirect or :term:`virtual `) subclass thereof. If *object* is not
an object of the given type, the function always returns ``False``.
If *classinfo* is a tuple of type objects (or recursively, other such
@@ -913,12 +910,13 @@ are always available. They are listed here in alphabetical order.
.. function:: issubclass(class, classinfo)
- Return ``True`` if *class* is a subclass (direct, indirect or :term:`virtual
+ Return ``True`` if *class* is a subclass (direct, indirect, or :term:`virtual