diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml
index 199547432be294..6302b547982118 100644
--- a/.azure-pipelines/ci.yml
+++ b/.azure-pipelines/ci.yml
@@ -1,14 +1,14 @@
variables:
coverage: false
-trigger: ['main', '3.10', '3.9', '3.8', '3.7']
+trigger: ['main', '3.11', '3.10', '3.9', '3.8', '3.7']
jobs:
- job: Prebuild
displayName: Pre-build checks
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
steps:
- template: ./prebuild-checks.yml
@@ -20,7 +20,7 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
steps:
- template: ./docs-steps.yml
@@ -52,12 +52,12 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
variables:
testRunTitle: '$(build.sourceBranchName)-linux'
testRunPlatform: linux
- openssl_version: 1.1.1n
+ openssl_version: 1.1.1t
steps:
- template: ./posix-steps.yml
@@ -78,12 +78,12 @@ jobs:
)
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
variables:
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
testRunPlatform: linux-coverage
- openssl_version: 1.1.1n
+ openssl_version: 1.1.1t
steps:
- template: ./posix-steps.yml
diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml
index b96a192005a42d..5f7218768c18af 100644
--- a/.azure-pipelines/pr.yml
+++ b/.azure-pipelines/pr.yml
@@ -1,14 +1,14 @@
variables:
coverage: false
-pr: ['main', '3.10', '3.9', '3.8', '3.7']
+pr: ['main', '3.11', '3.10', '3.9', '3.8', '3.7']
jobs:
- job: Prebuild
displayName: Pre-build checks
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
steps:
- template: ./prebuild-checks.yml
@@ -20,7 +20,7 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
steps:
- template: ./docs-steps.yml
@@ -52,12 +52,12 @@ jobs:
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
variables:
testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
testRunPlatform: linux
- openssl_version: 1.1.1n
+ openssl_version: 1.1.1t
steps:
- template: ./posix-steps.yml
@@ -78,12 +78,12 @@ jobs:
)
pool:
- vmImage: ubuntu-20.04
+ vmImage: ubuntu-22.04
variables:
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
testRunPlatform: linux-coverage
- openssl_version: 1.1.1n
+ openssl_version: 1.1.1t
steps:
- template: ./posix-steps.yml
diff --git a/.azure-pipelines/windows-layout-steps.yml b/.azure-pipelines/windows-layout-steps.yml
index e15729fac3443d..afd89781790494 100644
--- a/.azure-pipelines/windows-layout-steps.yml
+++ b/.azure-pipelines/windows-layout-steps.yml
@@ -12,7 +12,7 @@ steps:
displayName: Show layout info (${{ parameters.kind }})
- ${{ if eq(parameters.fulltest, 'true') }}:
- - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)"
+ - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)" -i test_launcher
workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
displayName: ${{ parameters.kind }} Tests
env:
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 62ee6f89cda679..3d39e0c4ef0417 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,6 +4,9 @@
# It uses the same pattern rule for gitignore file
# https://git-scm.com/docs/gitignore#_pattern_format
+# GitHub
+.github/** @ezio-melotti
+
# asyncio
**/*asyncio* @1st1 @asvetlov
@@ -98,7 +101,7 @@ Lib/ast.py @isidentical
/Lib/unittest/test/testmock/* @cjw296
# SQLite 3
-**/*sqlite* @berkerpeksag
+**/*sqlite* @berkerpeksag @erlend-aasland
# subprocess
/Lib/subprocess.py @gpshead
@@ -130,7 +133,7 @@ Lib/ast.py @isidentical
**/*idlelib* @terryjreedy
-**/*typing* @gvanrossum @Fidget-Spinner @JelleZijlstra
+**/*typing* @gvanrossum @Fidget-Spinner @JelleZijlstra @AlexWaygood
**/*asyncore @giampaolo
**/*asynchat @giampaolo
diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst
index 30a39a40494fde..f4affee76e1d44 100644
--- a/.github/CONTRIBUTING.rst
+++ b/.github/CONTRIBUTING.rst
@@ -6,19 +6,19 @@ Build Status
- main
- + `Stable buildbots `_
+ + `Stable buildbots `_
- 3.9
- + `Stable buildbots `_
+ + `Stable buildbots `_
- 3.8
- + `Stable buildbots `_
+ + `Stable buildbots `_
- 3.7
- + `Stable buildbots `_
+ + `Stable buildbots `_
Thank You
@@ -38,7 +38,7 @@ also suggestions on how you can most effectively help the project.
Please be aware that our workflow does deviate slightly from the typical GitHub
project. Details on how to properly submit a pull request are covered in
-`Lifecycle of a Pull Request `_.
+`Lifecycle of a Pull Request `_.
We utilize various bots and status checks to help with this, so do follow the
comments they leave and their "Details" links, respectively. The key points of
our workflow that are not covered by a bot or status check are:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b489335903772c..20df0923cde72f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -8,6 +8,7 @@ on:
push:
branches:
- 'main'
+ - '3.11'
- '3.10'
- '3.9'
- '3.8'
@@ -15,26 +16,36 @@ on:
pull_request:
branches:
- 'main'
+ - '3.11'
- '3.10'
- '3.9'
- '3.8'
- '3.7'
+permissions:
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
jobs:
check_source:
name: 'Check for source changes'
runs-on: ubuntu-latest
+ timeout-minutes: 10
outputs:
run_tests: ${{ steps.check.outputs.run_tests }}
run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }}
+ config_hash: ${{ steps.config_hash.outputs.hash }}
steps:
- uses: actions/checkout@v3
- name: Check for source changes
id: check
run: |
if [ -z "$GITHUB_BASE_REF" ]; then
- echo '::set-output name=run_tests::true'
- echo '::set-output name=run_ssl_tests::true'
+ echo "run_tests=true" >> $GITHUB_OUTPUT
+ echo "run_ssl_tests=true" >> $GITHUB_OUTPUT
else
git fetch origin $GITHUB_BASE_REF --depth=1
# git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
@@ -50,24 +61,64 @@ jobs:
# into the PR branch anyway.
#
# https://github.com/python/core-workflow/issues/373
- git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo '::set-output name=run_tests::true' || true
- git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo '::set-output name=run_ssl_tests::true' || true
+ git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true
+ git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo "run_ssl_tests=true" >> $GITHUB_OUTPUT || true
+ fi
+ - name: Compute hash for config cache key
+ id: config_hash
+ run: |
+ echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT
+
+ 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: |
+ if ! make check-abidump; 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
+ timeout-minutes: 60
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
steps:
- uses: actions/checkout@v3
+ - name: Restore config.cache
+ uses: actions/cache@v3
+ with:
+ path: config.cache
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
- 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
+ uses: hendrikmuhs/ccache-action@v1.2
- name: Check Autoconf version 2.69 and aclocal 1.16.3
run: |
grep "Generated by GNU Autoconf 2.69" configure
@@ -77,7 +128,7 @@ jobs:
- name: Configure CPython
run: |
# Build Python with the libpython dynamic library
- ./configure --with-pydebug --enable-shared
+ ./configure --config-cache --with-pydebug --enable-shared
- name: Regenerate autoconf files with container image
run: make regen-configure
- name: Build CPython
@@ -109,6 +160,7 @@ jobs:
build_win32:
name: 'Windows (x86)'
runs-on: windows-latest
+ timeout-minutes: 60
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:
@@ -117,7 +169,6 @@ jobs:
- uses: actions/checkout@v3
- name: Build CPython
run: .\PCbuild\build.bat -e -d -p Win32
- timeout-minutes: 30
- name: Display build info
run: .\python.bat -m test.pythoninfo
- name: Tests
@@ -126,6 +177,7 @@ jobs:
build_win_amd64:
name: 'Windows (x64)'
runs-on: windows-latest
+ timeout-minutes: 60
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:
@@ -136,7 +188,6 @@ jobs:
run: echo "::add-matcher::.github/problem-matchers/msvc.json"
- name: Build CPython
run: .\PCbuild\build.bat -e -d -p x64
- timeout-minutes: 30
- name: Display build info
run: .\python.bat -m test.pythoninfo
- name: Tests
@@ -145,18 +196,33 @@ jobs:
build_macos:
name: 'macOS'
runs-on: macos-latest
+ timeout-minutes: 60
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:
+ HOMEBREW_NO_ANALYTICS: 1
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
PYTHONSTRICTEXTENSIONBUILD: 1
steps:
- 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: Restore config.cache
+ uses: actions/cache@v3
+ with:
+ path: config.cache
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
+ - name: Install Homebrew dependencies
+ run: brew install pkg-config openssl@1.1 xz gdbm tcl-tk
- name: Configure CPython
- run: ./configure --with-pydebug --prefix=/opt/python-dev
+ run: |
+ CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \
+ LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \
+ PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
+ ./configure \
+ --config-cache \
+ --with-pydebug \
+ --prefix=/opt/python-dev \
+ --with-openssl="$(brew --prefix openssl@1.1)"
- name: Build CPython
run: make -j4
- name: Display build info
@@ -167,10 +233,11 @@ jobs:
build_ubuntu:
name: 'Ubuntu'
runs-on: ubuntu-20.04
+ timeout-minutes: 60
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:
- OPENSSL_VER: 1.1.1n
+ OPENSSL_VER: 1.1.1t
PYTHONSTRICTEXTENSIONBUILD: 1
steps:
- uses: actions/checkout@v3
@@ -196,7 +263,7 @@ jobs:
run: |
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
- name: Configure ccache action
- uses: hendrikmuhs/ccache-action@v1
+ uses: hendrikmuhs/ccache-action@v1.2
- name: Setup directory envs for out-of-tree builds
run: |
echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV
@@ -205,9 +272,18 @@ jobs:
run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR
- name: Bind mount sources read-only
run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR
+ - name: Restore config.cache
+ uses: actions/cache@v3
+ with:
+ path: ${{ env.CPYTHON_BUILDDIR }}/config.cache
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
- name: Configure CPython out-of-tree
working-directory: ${{ env.CPYTHON_BUILDDIR }}
- run: ../cpython-ro-srcdir/configure --with-pydebug --with-openssl=$OPENSSL_DIR
+ run: |
+ ../cpython-ro-srcdir/configure \
+ --config-cache \
+ --with-pydebug \
+ --with-openssl=$OPENSSL_DIR
- name: Build CPython out-of-tree
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: make -j4
@@ -224,12 +300,13 @@ jobs:
build_ubuntu_ssltests:
name: 'Ubuntu SSL tests with OpenSSL'
runs-on: ubuntu-20.04
+ timeout-minutes: 60
needs: check_source
if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true'
strategy:
fail-fast: false
matrix:
- openssl_ver: [1.1.1n, 3.0.2]
+ openssl_ver: [1.1.1t, 3.0.8, 3.1.0-beta1]
env:
OPENSSL_VER: ${{ matrix.openssl_ver }}
MULTISSL_DIR: ${{ github.workspace }}/multissl
@@ -237,6 +314,11 @@ jobs:
LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib
steps:
- uses: actions/checkout@v3
+ - name: Restore config.cache
+ uses: actions/cache@v3
+ with:
+ path: config.cache
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install Dependencies
@@ -259,9 +341,9 @@ jobs:
run: |
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
- name: Configure ccache action
- uses: hendrikmuhs/ccache-action@v1
+ uses: hendrikmuhs/ccache-action@v1.2
- name: Configure CPython
- run: ./configure --with-pydebug --with-openssl=$OPENSSL_DIR
+ run: ./configure --config-cache --with-pydebug --with-openssl=$OPENSSL_DIR
- name: Build CPython
run: make -j4
- name: Display build info
@@ -269,22 +351,31 @@ jobs:
- name: SSL tests
run: ./python Lib/test/ssltests.py
-
build_asan:
name: 'Address sanitizer'
runs-on: ubuntu-20.04
+ timeout-minutes: 60
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:
- OPENSSL_VER: 1.1.1n
+ OPENSSL_VER: 1.1.1t
PYTHONSTRICTEXTENSIONBUILD: 1
ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0
steps:
- uses: actions/checkout@v3
+ - name: Restore config.cache
+ uses: actions/cache@v3
+ with:
+ path: config.cache
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install Dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
+ - name: Set up GCC-10 for ASAN
+ uses: egor-tensin/setup-gcc@v1
+ with:
+ version: 10
- name: Configure OpenSSL env vars
run: |
echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV
@@ -303,9 +394,9 @@ jobs:
run: |
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
- name: Configure ccache action
- uses: hendrikmuhs/ccache-action@v1
+ uses: hendrikmuhs/ccache-action@v1.2
- name: Configure CPython
- run: ./configure --with-address-sanitizer --without-pymalloc
+ run: ./configure --config-cache --with-address-sanitizer --without-pymalloc
- name: Build CPython
run: make -j4
- name: Display build info
diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml
index cba1e51ef27d3a..1b9c1d141d13cc 100644
--- a/.github/workflows/build_msi.yml
+++ b/.github/workflows/build_msi.yml
@@ -5,6 +5,7 @@ on:
push:
branches:
- 'main'
+ - '3.11'
- '3.10'
- '3.9'
- '3.8'
@@ -14,6 +15,7 @@ on:
pull_request:
branches:
- 'main'
+ - '3.11'
- '3.10'
- '3.9'
- '3.8'
@@ -21,10 +23,18 @@ on:
paths:
- 'Tools/msi/**'
+permissions:
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
jobs:
build_win32:
name: 'Windows (x86) Installer'
runs-on: windows-latest
+ timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- name: Build CPython installer
@@ -33,6 +43,7 @@ jobs:
build_win_amd64:
name: 'Windows (x64) Installer'
runs-on: windows-latest
+ timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- name: Build CPython installer
@@ -41,6 +52,7 @@ jobs:
build_win_arm64:
name: 'Windows (ARM64) Installer'
runs-on: windows-latest
+ timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- name: Build CPython installer
diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml
index 3ed66e74b89542..e32078c67fba60 100644
--- a/.github/workflows/doc.yml
+++ b/.github/workflows/doc.yml
@@ -5,6 +5,7 @@ on:
#push:
# branches:
# - 'main'
+ # - '3.11'
# - '3.10'
# - '3.9'
# - '3.8'
@@ -14,6 +15,7 @@ on:
pull_request:
branches:
- 'main'
+ - '3.11'
- '3.10'
- '3.9'
- '3.8'
@@ -21,15 +23,77 @@ on:
paths:
- 'Doc/**'
- 'Misc/**'
+ - '.github/workflows/doc.yml'
+
+permissions:
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
jobs:
build_doc:
name: 'Docs'
runs-on: ubuntu-latest
+ timeout-minutes: 60
+ steps:
+ - 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/ check
+ - 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
+
+ # This build doesn't use problem matchers or check annotations
+ # It also does not run 'make check', as sphinx-lint is not installed into the
+ # environment.
+ build_doc_oldest_supported_sphinx:
+ name: 'Docs (Oldest Sphinx)'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ steps:
+ - uses: actions/checkout@v3
+ - name: 'Set up Python'
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.11' # known to work with Sphinx 3.2
+ cache: 'pip'
+ cache-dependency-path: 'Doc/requirements-oldest-sphinx.txt'
+ - name: 'Install build dependencies'
+ run: make -C Doc/ venv REQUIREMENTS="requirements-oldest-sphinx.txt"
+ - name: 'Build HTML documentation'
+ run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html
+
+ # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release
+ doctest:
+ name: 'Doctest'
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
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'
@@ -38,17 +102,6 @@ jobs:
run: make -j4
- name: 'Install build dependencies'
run: make -C Doc/ PYTHON=../python venv
- # Run "check doctest html" as 3 steps to get a more readable output
- # in the web UI
- - name: 'Check documentation'
- run: make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" check
# Use "xvfb-run" since some doctest tests open GUI windows
- name: 'Run documentation doctest'
- run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" doctest
- - name: 'Build HTML documentation'
- run: make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" html
- - name: 'Upload'
- uses: actions/upload-artifact@v3
- with:
- name: doc-html
- path: Doc/build/html
+ run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" doctest
diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml
new file mode 100644
index 00000000000000..43a7afec73884e
--- /dev/null
+++ b/.github/workflows/documentation-links.yml
@@ -0,0 +1,27 @@
+name: Read the Docs PR preview
+# Automatically edits a pull request's descriptions with a link
+# to the documentation's preview on Read the Docs.
+
+on:
+ pull_request_target:
+ types:
+ - opened
+ paths:
+ - 'Doc/**'
+ - '.github/workflows/doc.yml'
+
+permissions:
+ pull-requests: write
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ documentation-links:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: readthedocs/actions/preview@v1
+ with:
+ project-slug: "cpython-previews"
+ single-version: "true"
diff --git a/.github/workflows/new-bugs-announce-notifier.yml b/.github/workflows/new-bugs-announce-notifier.yml
index 8cd834419f00bf..d3b982455dd970 100644
--- a/.github/workflows/new-bugs-announce-notifier.yml
+++ b/.github/workflows/new-bugs-announce-notifier.yml
@@ -5,9 +5,13 @@ on:
types:
- opened
+permissions:
+ issues: read
+
jobs:
notify-new-bugs-announce:
runs-on: ubuntu-latest
+ timeout-minutes: 10
steps:
- uses: actions/setup-node@v3
with:
@@ -39,7 +43,7 @@ jobs:
assignee : issue.data.assignees.map(assignee => { return assignee.login }),
body : issue.data.body
};
-
+
const data = {
from: "CPython Issues ",
to: "new-bugs-announce@python.org",
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/require-pr-label.yml b/.github/workflows/require-pr-label.yml
new file mode 100644
index 00000000000000..916bbeb4352734
--- /dev/null
+++ b/.github/workflows/require-pr-label.yml
@@ -0,0 +1,18 @@
+name: Check labels
+
+on:
+ pull_request:
+ types: [opened, reopened, labeled, unlabeled, synchronize]
+
+jobs:
+ label:
+ name: DO-NOT-MERGE / unresolved review
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+
+ steps:
+ - uses: mheap/github-action-required-labels@v4
+ with:
+ mode: exactly
+ count: 0
+ labels: "DO-NOT-MERGE, awaiting changes, awaiting change review"
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index f422707afb9e5c..81fb838728bd34 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -12,6 +12,7 @@ jobs:
if: github.repository_owner == 'python'
runs-on: ubuntu-latest
+ timeout-minutes: 10
steps:
- name: "Check PRs"
diff --git a/.github/workflows/verify-ensurepip-wheels.yml b/.github/workflows/verify-ensurepip-wheels.yml
new file mode 100644
index 00000000000000..030fbc6ce29555
--- /dev/null
+++ b/.github/workflows/verify-ensurepip-wheels.yml
@@ -0,0 +1,33 @@
+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
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ verify:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ 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 b3b22f471c2765..d42e111666f1e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -114,6 +114,7 @@ PCbuild/win32/
Tools/unicode/data/
/autom4te.cache
/build/
+/builddir/
/config.cache
/config.log
/config.status
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 00000000000000..013c839ed6b7a4
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,3 @@
+# This file sets the canonical name for contributors to the repository.
+# Documentation: https://git-scm.com/docs/gitmailmap
+Amethyst Reese
diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 00000000000000..898a9ae89dbb92
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,18 @@
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+# Project page: https://readthedocs.org/projects/cpython-previews/
+
+version: 2
+
+sphinx:
+ configuration: Doc/conf.py
+
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3"
+
+ commands:
+ - make -C Doc venv html
+ - mkdir _readthedocs
+ - mv Doc/build/html _readthedocs/html
diff --git a/Doc/Makefile b/Doc/Makefile
index 3a3417bf99af3b..918814140f45cb 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -9,16 +9,18 @@ VENVDIR = ./venv
SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-build
SPHINXLINT = PATH=$(VENVDIR)/bin:$$PATH sphinx-lint
BLURB = PATH=$(VENVDIR)/bin:$$PATH blurb
+JOBS = auto
PAPER =
SOURCES =
DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py)
+REQUIREMENTS = requirements.txt
SPHINXERRORHANDLING = -W
# Internal variables.
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 $(JOBS) \
$(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES)
.PHONY: help build html htmlhelp latex text texinfo changes linkcheck \
@@ -153,8 +155,8 @@ venv:
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; \
+ $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \
+ $(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \
echo "The venv has been created in the $(VENVDIR) directory"; \
fi
@@ -213,8 +215,10 @@ dist:
rm dist/python-$(DISTVERSION)-docs-texinfo.tar
check:
- $(SPHINXLINT) -i tools -i $(VENVDIR) -i README.rst
- $(SPHINXLINT) ../Misc/NEWS.d/next/
+ # Check the docs and NEWS files with sphinx-lint.
+ # Ignore the tools and venv dirs and check that the default role is not used.
+ $(SPHINXLINT) -i tools -i $(VENVDIR) --enable default-role
+ $(SPHINXLINT) --enable default-role ../Misc/NEWS.d/next/
serve:
@echo "The serve target was removed, use htmlview instead (see bpo-36329)"
diff --git a/Doc/README.rst b/Doc/README.rst
index 4326086e9e3529..d67cad79916b38 100644
--- a/Doc/README.rst
+++ b/Doc/README.rst
@@ -40,7 +40,7 @@ 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``
+the Makefile will look for instances of ``sphinx-build`` and ``blurb``
installed on your process ``PATH`` (configurable with the ``SPHINXBUILD`` and
``BLURB`` variables).
diff --git a/Doc/_static/og-image.png b/Doc/_static/og-image.png
new file mode 100644
index 00000000000000..0e80751e740387
Binary files /dev/null and b/Doc/_static/og-image.png differ
diff --git a/Doc/about.rst b/Doc/about.rst
index f0b908487b2d09..5e6160ff2700ed 100644
--- a/Doc/about.rst
+++ b/Doc/about.rst
@@ -6,8 +6,8 @@ About these documents
These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a
document processor specifically written for the Python documentation.
-.. _reStructuredText: http://docutils.sourceforge.net/rst.html
-.. _Sphinx: http://sphinx-doc.org/
+.. _reStructuredText: https://docutils.sourceforge.io/rst.html
+.. _Sphinx: https://www.sphinx-doc.org/
.. In the online version of these documents, you can submit comments and suggest
changes directly on the documentation pages.
@@ -21,7 +21,7 @@ Many thanks go to:
* Fred L. Drake, Jr., the creator of the original Python documentation toolset
and writer of much of the content;
-* the `Docutils `_ project for creating
+* 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.
diff --git a/Doc/bugs.rst b/Doc/bugs.rst
index 69d7c27410d56a..d98192b369603e 100644
--- a/Doc/bugs.rst
+++ b/Doc/bugs.rst
@@ -19,6 +19,9 @@ If you find a bug in this documentation or would like to propose an improvement,
please submit a bug report on the :ref:`tracker `. If you
have a suggestion on how to fix it, include that as well.
+You can also open a discussion item on our
+`Documentation Discourse forum `_.
+
If you're short on time, you can also email documentation bug reports to
docs@python.org (behavioral bugs can be sent to python-list@python.org).
'docs@' is a mailing list run by volunteers; your request will be noticed,
@@ -67,7 +70,7 @@ Click on the "New issue" button in the top bar to report a new issue.
The submission form has two fields, "Title" and "Comment".
For the "Title" field, enter a *very* short description of the problem;
-less than ten words is good.
+fewer than ten words is good.
In the "Comment" field, describe the problem in detail, including what you
expected to happen and what did happen. Be sure to include whether any
diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst
index 33b0c06a9ebc2e..0a8fcc5ae5fcdf 100644
--- a/Doc/c-api/allocation.rst
+++ b/Doc/c-api/allocation.rst
@@ -14,7 +14,7 @@ Allocating Objects on the Heap
.. c:function:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type)
- Initialize a newly-allocated object *op* with its type and initial
+ Initialize a newly allocated object *op* with its type and initial
reference. Returns the initialized object. If *type* indicates that the
object participates in the cyclic garbage detector, it is added to the
detector's set of observed objects. Other fields of the object are not
diff --git a/Doc/c-api/apiabiversion.rst b/Doc/c-api/apiabiversion.rst
index 85b6e2f373877f..62d542966622ce 100644
--- a/Doc/c-api/apiabiversion.rst
+++ b/Doc/c-api/apiabiversion.rst
@@ -58,6 +58,8 @@ See :ref:`stable` for a discussion of API and ABI stability across versions.
Thus ``3.4.1a2`` is hexversion ``0x030401a2`` and ``3.10.0`` is
hexversion ``0x030a00f0``.
+ Use this for numeric comparisons, e.g. ``#if PY_VERSION_HEX >= ...``.
+
This version is also available via the symbol :data:`Py_Version`.
.. c:var:: const unsigned long Py_Version
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 1d93b35dc1c884..6a53c79bd3becf 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -34,24 +34,39 @@ These formats allow accessing an object as a contiguous chunk of memory.
You don't have to provide raw storage for the returned unicode or bytes
area.
-In general, when a format sets a pointer to a buffer, the buffer is
-managed by the corresponding Python object, and the buffer shares
-the lifetime of this object. You won't have to release any memory yourself.
-The only exceptions are ``es``, ``es#``, ``et`` and ``et#``.
-
-However, when a :c:type:`Py_buffer` structure gets filled, the underlying
-buffer is locked so that the caller can subsequently use the buffer even
-inside a :c:type:`Py_BEGIN_ALLOW_THREADS` block without the risk of mutable data
-being resized or destroyed. As a result, **you have to call**
-:c:func:`PyBuffer_Release` after you have finished processing the data (or
-in any early abort case).
-
Unless otherwise stated, buffers are not NUL-terminated.
-Some formats require a read-only :term:`bytes-like object`, and set a
-pointer instead of a buffer structure. They work by checking that
-the object's :c:member:`PyBufferProcs.bf_releasebuffer` field is ``NULL``,
-which disallows mutable objects such as :class:`bytearray`.
+There are three ways strings and buffers can be converted to C:
+
+* Formats such as ``y*`` and ``s*`` fill a :c:type:`Py_buffer` structure.
+ This locks the underlying buffer so that the caller can subsequently use
+ the buffer even inside a :c:type:`Py_BEGIN_ALLOW_THREADS`
+ block without the risk of mutable data being resized or destroyed.
+ As a result, **you have to call** :c:func:`PyBuffer_Release` after you have
+ finished processing the data (or in any early abort case).
+
+* The ``es``, ``es#``, ``et`` and ``et#`` formats allocate the result buffer.
+ **You have to call** :c:func:`PyMem_Free` after you have finished
+ processing the data (or in any early abort case).
+
+* .. _c-arg-borrowed-buffer:
+
+ Other formats take a :class:`str` or a read-only :term:`bytes-like object`,
+ such as :class:`bytes`, and provide a ``const char *`` pointer to
+ its buffer.
+ In this case the buffer is "borrowed": it is managed by the corresponding
+ Python object, and shares the lifetime of this object.
+ You won't have to release any memory yourself.
+
+ To ensure that the underlying buffer may be safely borrowed, the object's
+ :c:member:`PyBufferProcs.bf_releasebuffer` field must be ``NULL``.
+ This disallows common mutable objects such as :class:`bytearray`,
+ but also some read-only objects such as :class:`memoryview` of
+ :class:`bytes`.
+
+ Besides this ``bf_releasebuffer`` requirement, there is no check to verify
+ whether the input object is immutable (e.g. whether it would honor a request
+ for a writable buffer, or whether another thread can mutate the data).
.. note::
@@ -89,7 +104,7 @@ which disallows mutable objects such as :class:`bytearray`.
Unicode objects are converted to C strings using ``'utf-8'`` encoding.
``s#`` (:class:`str`, read-only :term:`bytes-like object`) [const char \*, :c:type:`Py_ssize_t`]
- Like ``s*``, except that it doesn't accept mutable objects.
+ Like ``s*``, except that it provides a :ref:`borrowed buffer `.
The result is stored into two C variables,
the first one a pointer to a C string, the second one its length.
The string may contain embedded null bytes. Unicode objects are converted
@@ -108,8 +123,9 @@ which disallows mutable objects such as :class:`bytearray`.
pointer is set to ``NULL``.
``y`` (read-only :term:`bytes-like object`) [const char \*]
- This format converts a bytes-like object to a C pointer to a character
- string; it does not accept Unicode objects. The bytes buffer must not
+ This format converts a bytes-like object to a C pointer to a
+ :ref:`borrowed ` character string;
+ it does not accept Unicode objects. The bytes buffer must not
contain embedded null bytes; if it does, a :exc:`ValueError`
exception is raised.
@@ -129,12 +145,12 @@ which disallows mutable objects such as :class:`bytearray`.
``S`` (:class:`bytes`) [PyBytesObject \*]
Requires that the Python object is a :class:`bytes` object, without
attempting any conversion. Raises :exc:`TypeError` if the object is not
- a bytes object. The C variable may also be declared as :c:type:`PyObject*`.
+ a bytes object. The C variable may also be declared as :c:expr:`PyObject*`.
``Y`` (:class:`bytearray`) [PyByteArrayObject \*]
Requires that the Python object is a :class:`bytearray` object, without
attempting any conversion. Raises :exc:`TypeError` if the object is not
- a :class:`bytearray` object. The C variable may also be declared as :c:type:`PyObject*`.
+ a :class:`bytearray` object. The C variable may also be declared as :c:expr:`PyObject*`.
``u`` (:class:`str`) [const Py_UNICODE \*]
Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of
@@ -181,7 +197,7 @@ which disallows mutable objects such as :class:`bytearray`.
``U`` (:class:`str`) [PyObject \*]
Requires that the Python object is a Unicode object, without attempting
any conversion. Raises :exc:`TypeError` if the object is not a Unicode
- object. The C variable may also be declared as :c:type:`PyObject*`.
+ object. The C variable may also be declared as :c:expr:`PyObject*`.
``w*`` (read-write :term:`bytes-like object`) [Py_buffer]
This format accepts any object which implements the read-write buffer
@@ -194,10 +210,10 @@ which disallows mutable objects such as :class:`bytearray`.
It only works for encoded data without embedded NUL bytes.
This format requires two arguments. The first is only used as input, and
- must be a :c:type:`const char*` which points to the name of an encoding as a
+ must be a :c:expr:`const char*` which points to the name of an encoding as a
NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
An exception is raised if the named encoding is not known to Python. The
- second argument must be a :c:type:`char**`; the value of the pointer it
+ second argument must be a :c:expr:`char**`; the value of the pointer it
references will be set to a buffer with the contents of the argument text.
The text will be encoded in the encoding specified by the first argument.
@@ -217,10 +233,10 @@ which disallows mutable objects such as :class:`bytearray`.
characters.
It requires three arguments. The first is only used as input, and must be a
- :c:type:`const char*` which points to the name of an encoding as a
+ :c:expr:`const char*` which points to the name of an encoding as a
NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
An exception is raised if the named encoding is not known to Python. The
- second argument must be a :c:type:`char**`; the value of the pointer it
+ second argument must be a :c:expr:`char**`; the value of the pointer it
references will be set to a buffer with the contents of the argument text.
The text will be encoded in the encoding specified by the first argument.
The third argument must be a pointer to an integer; the referenced integer
@@ -252,59 +268,59 @@ Numbers
``b`` (:class:`int`) [unsigned char]
Convert a nonnegative Python integer to an unsigned tiny int, stored in a C
- :c:type:`unsigned char`.
+ :c:expr:`unsigned char`.
``B`` (:class:`int`) [unsigned char]
Convert a Python integer to a tiny int without overflow checking, stored in a C
- :c:type:`unsigned char`.
+ :c:expr:`unsigned char`.
``h`` (:class:`int`) [short int]
- Convert a Python integer to a C :c:type:`short int`.
+ Convert a Python integer to a C :c:expr:`short int`.
``H`` (:class:`int`) [unsigned short int]
- Convert a Python integer to a C :c:type:`unsigned short int`, without overflow
+ Convert a Python integer to a C :c:expr:`unsigned short int`, without overflow
checking.
``i`` (:class:`int`) [int]
- Convert a Python integer to a plain C :c:type:`int`.
+ Convert a Python integer to a plain C :c:expr:`int`.
``I`` (:class:`int`) [unsigned int]
- Convert a Python integer to a C :c:type:`unsigned int`, without overflow
+ Convert a Python integer to a C :c:expr:`unsigned int`, without overflow
checking.
``l`` (:class:`int`) [long int]
- Convert a Python integer to a C :c:type:`long int`.
+ Convert a Python integer to a C :c:expr:`long int`.
``k`` (:class:`int`) [unsigned long]
- Convert a Python integer to a C :c:type:`unsigned long` without
+ Convert a Python integer to a C :c:expr:`unsigned long` without
overflow checking.
``L`` (:class:`int`) [long long]
- Convert a Python integer to a C :c:type:`long long`.
+ Convert a Python integer to a C :c:expr:`long long`.
``K`` (:class:`int`) [unsigned long long]
- Convert a Python integer to a C :c:type:`unsigned long long`
+ Convert a Python integer to a C :c:expr:`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]
Convert a Python byte, represented as a :class:`bytes` or
- :class:`bytearray` object of length 1, to a C :c:type:`char`.
+ :class:`bytearray` object of length 1, to a C :c:expr:`char`.
.. versionchanged:: 3.3
Allow :class:`bytearray` objects.
``C`` (:class:`str` of length 1) [int]
Convert a Python character, represented as a :class:`str` object of
- length 1, to a C :c:type:`int`.
+ length 1, to a C :c:expr:`int`.
``f`` (:class:`float`) [float]
- Convert a Python floating point number to a C :c:type:`float`.
+ Convert a Python floating point number to a C :c:expr:`float`.
``d`` (:class:`float`) [double]
- Convert a Python floating point number to a C :c:type:`double`.
+ Convert a Python floating point number to a C :c:expr:`double`.
``D`` (:class:`complex`) [Py_complex]
Convert a Python complex number to a C :c:type:`Py_complex` structure.
@@ -320,7 +336,7 @@ Other objects
``O!`` (object) [*typeobject*, PyObject \*]
Store a Python object in a C object pointer. This is similar to ``O``, but
takes two C arguments: the first is the address of a Python type object, the
- second is the address of the C variable (of type :c:type:`PyObject*`) into which
+ second is the address of the C variable (of type :c:expr:`PyObject*`) into which
the object pointer is stored. If the Python object does not have the required
type, :exc:`TypeError` is raised.
@@ -329,13 +345,13 @@ Other objects
``O&`` (object) [*converter*, *anything*]
Convert a Python object to a C variable through a *converter* function. This
takes two arguments: the first is a function, the second is the address of a C
- variable (of arbitrary type), converted to :c:type:`void *`. The *converter*
+ variable (of arbitrary type), converted to :c:expr:`void *`. The *converter*
function in turn is called as follows::
status = converter(object, address);
where *object* is the Python object to be converted and *address* is the
- :c:type:`void*` argument that was passed to the :c:func:`PyArg_Parse\*` function.
+ :c:expr:`void*` argument that was passed to the ``PyArg_Parse*`` function.
The returned *status* should be ``1`` for a successful conversion and ``0`` if
the conversion has failed. When the conversion fails, the *converter* function
should raise an exception and leave the content of *address* unmodified.
@@ -409,9 +425,9 @@ what is specified for the corresponding format unit in that case.
For the conversion to succeed, the *arg* object must match the format
and the format must be exhausted. On success, the
-:c:func:`PyArg_Parse\*` functions return true, otherwise they return
+``PyArg_Parse*`` functions return true, otherwise they return
false and raise an appropriate exception. When the
-:c:func:`PyArg_Parse\*` functions fail due to conversion failure in one
+``PyArg_Parse*`` functions fail due to conversion failure in one
of the format units, the variables at the addresses corresponding to that
and the following format units are left untouched.
@@ -481,7 +497,7 @@ API Functions
*args*; it must actually be a tuple. The length of the tuple must be at least
*min* and no more than *max*; *min* and *max* may be equal. Additional
arguments must be passed to the function, each of which should be a pointer to a
- :c:type:`PyObject*` variable; these will be filled in with the values from
+ :c:expr:`PyObject*` variable; these will be filled in with the values from
*args*; they will contain :term:`borrowed references `.
The variables which correspond
to optional parameters not given by *args* will not be filled in; these should
@@ -518,7 +534,7 @@ Building values
.. c:function:: PyObject* Py_BuildValue(const char *format, ...)
Create a new value based on a format string similar to those accepted by the
- :c:func:`PyArg_Parse\*` family of functions and a sequence of values. Returns
+ ``PyArg_Parse*`` family of functions and a sequence of values. Returns
the value or ``NULL`` in the case of an error; an exception will be raised if
``NULL`` is returned.
@@ -568,7 +584,7 @@ Building values
Same as ``s#``.
``u`` (:class:`str`) [const wchar_t \*]
- Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4)
+ Convert a null-terminated :c:expr:`wchar_t` buffer of Unicode (UTF-16 or UCS-4)
data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``,
``None`` is returned.
@@ -584,51 +600,51 @@ Building values
Same as ``s#``.
``i`` (:class:`int`) [int]
- Convert a plain C :c:type:`int` to a Python integer object.
+ Convert a plain C :c:expr:`int` to a Python integer object.
``b`` (:class:`int`) [char]
- Convert a plain C :c:type:`char` to a Python integer object.
+ Convert a plain C :c:expr:`char` to a Python integer object.
``h`` (:class:`int`) [short int]
- Convert a plain C :c:type:`short int` to a Python integer object.
+ Convert a plain C :c:expr:`short int` to a Python integer object.
``l`` (:class:`int`) [long int]
- Convert a C :c:type:`long int` to a Python integer object.
+ Convert a C :c:expr:`long int` to a Python integer object.
``B`` (:class:`int`) [unsigned char]
- Convert a C :c:type:`unsigned char` to a Python integer object.
+ Convert a C :c:expr:`unsigned char` to a Python integer object.
``H`` (:class:`int`) [unsigned short int]
- Convert a C :c:type:`unsigned short int` to a Python integer object.
+ Convert a C :c:expr:`unsigned short int` to a Python integer object.
``I`` (:class:`int`) [unsigned int]
- Convert a C :c:type:`unsigned int` to a Python integer object.
+ Convert a C :c:expr:`unsigned int` to a Python integer object.
``k`` (:class:`int`) [unsigned long]
- Convert a C :c:type:`unsigned long` to a Python integer object.
+ Convert a C :c:expr:`unsigned long` to a Python integer object.
``L`` (:class:`int`) [long long]
- Convert a C :c:type:`long long` to a Python integer object.
+ Convert a C :c:expr:`long long` to a Python integer object.
``K`` (:class:`int`) [unsigned long long]
- Convert a C :c:type:`unsigned long long` to a Python integer object.
+ Convert a C :c:expr:`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]
- Convert a C :c:type:`int` representing a byte to a Python :class:`bytes` object of
+ Convert a C :c:expr:`int` representing a byte to a Python :class:`bytes` object of
length 1.
``C`` (:class:`str` of length 1) [int]
- Convert a C :c:type:`int` representing a character to Python :class:`str`
+ Convert a C :c:expr:`int` representing a character to Python :class:`str`
object of length 1.
``d`` (:class:`float`) [double]
- Convert a C :c:type:`double` to a Python floating point number.
+ Convert a C :c:expr:`double` to a Python floating point number.
``f`` (:class:`float`) [float]
- Convert a C :c:type:`float` to a Python floating point number.
+ Convert a C :c:expr:`float` to a Python floating point number.
``D`` (:class:`complex`) [Py_complex \*]
Convert a C :c:type:`Py_complex` structure to a Python complex number.
@@ -651,7 +667,7 @@ Building values
``O&`` (object) [*converter*, *anything*]
Convert *anything* to a Python object through a *converter* function. The
- function is called with *anything* (which should be compatible with :c:type:`void*`)
+ function is called with *anything* (which should be compatible with :c:expr:`void*`)
as its argument and should return a "new" Python object, or ``NULL`` if an
error occurred.
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index 05e131d06b909d..91d1edd9b2ec46 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -99,7 +99,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
For :term:`contiguous` arrays, the value points to the beginning of
the memory block.
- .. c:member:: void *obj
+ .. c:member:: PyObject *obj
A new reference to the exporting object. The reference is owned by
the consumer and automatically decremented and set to ``NULL`` by
@@ -499,7 +499,7 @@ Buffer-related functions
This function fails if *len* != *src->len*.
-.. c:function:: int PyObject_CopyData(Py_buffer *dest, Py_buffer *src)
+.. c:function:: int PyObject_CopyData(PyObject *dest, PyObject *src)
Copy data from *src* to *dest* buffer. Can convert between C-style and
or Fortran-style buffers.
diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst
index 4bf3cfe100cd01..456f7d89bca03c 100644
--- a/Doc/c-api/bytearray.rst
+++ b/Doc/c-api/bytearray.rst
@@ -5,7 +5,7 @@
Byte Array Objects
------------------
-.. index:: object: bytearray
+.. index:: pair: object; bytearray
.. c:type:: PyByteArrayObject
diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst
index d47f0422e61004..21a5ab931c8bfb 100644
--- a/Doc/c-api/bytes.rst
+++ b/Doc/c-api/bytes.rst
@@ -8,7 +8,7 @@ Bytes Objects
These functions raise :exc:`TypeError` when expecting a bytes parameter and
called with a non-bytes parameter.
-.. index:: object: bytes
+.. index:: pair: object; bytes
.. c:type:: PyBytesObject
@@ -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 cdf72bc1f4714a..36149f156c6764 100644
--- a/Doc/c-api/call.rst
+++ b/Doc/c-api/call.rst
@@ -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
@@ -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
@@ -283,7 +275,7 @@ please see individual documentation for details.
This is the equivalent of the Python expression: ``callable(*args)``.
- Note that if you only pass :c:type:`PyObject *` args,
+ Note that if you only pass :c:expr:`PyObject *` args,
:c:func:`PyObject_CallFunctionObjArgs` is a faster alternative.
.. versionchanged:: 3.4
@@ -304,7 +296,7 @@ please see individual documentation for details.
This is the equivalent of the Python expression:
``obj.name(arg1, arg2, ...)``.
- Note that if you only pass :c:type:`PyObject *` args,
+ Note that if you only pass :c:expr:`PyObject *` args,
:c:func:`PyObject_CallMethodObjArgs` is a faster alternative.
.. versionchanged:: 3.4
@@ -314,7 +306,7 @@ please see individual documentation for details.
.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...)
Call a callable Python object *callable*, with a variable number of
- :c:type:`PyObject *` arguments. The arguments are provided as a variable number
+ :c:expr:`PyObject *` arguments. The arguments are provided as a variable number
of parameters followed by *NULL*.
Return the result of the call on success, or raise an exception and return
@@ -328,7 +320,7 @@ please see individual documentation for details.
Call a method of the Python object *obj*, where the name of the method is given as a
Python string object in *name*. It is called with a variable number of
- :c:type:`PyObject *` arguments. The arguments are provided as a variable number
+ :c:expr:`PyObject *` arguments. The arguments are provided as a variable number
of parameters followed by *NULL*.
Return the result of the call on success, or raise an exception and return
@@ -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/capsule.rst b/Doc/c-api/capsule.rst
index 2c4cfc48f9a27a..427ed959c58568 100644
--- a/Doc/c-api/capsule.rst
+++ b/Doc/c-api/capsule.rst
@@ -5,7 +5,7 @@
Capsules
--------
-.. index:: object: Capsule
+.. index:: pair: object; Capsule
Refer to :ref:`using-capsules` for more information on using these objects.
@@ -15,7 +15,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
.. c:type:: PyCapsule
This subtype of :c:type:`PyObject` represents an opaque value, useful for C
- extension modules who need to pass an opaque value (as a :c:type:`void*`
+ extension modules who need to pass an opaque value (as a :c:expr:`void*`
pointer) through Python code to other C code. It is often used to make a C
function pointer defined in one module available to other modules, so the
regular import mechanism can be used to access C APIs defined in dynamically
diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst
index 7915b81b463773..ee39f2aea85b09 100644
--- a/Doc/c-api/code.rst
+++ b/Doc/c-api/code.rst
@@ -1,9 +1,9 @@
.. highlight:: c
-.. _codeobjects:
-
.. index:: object; code, code object
+.. _codeobjects:
+
Code Objects
------------
@@ -77,6 +77,8 @@ bound into a function.
Returns ``1`` if the function succeeds and 0 otherwise.
+ .. versionadded:: 3.11
+
.. c:function:: PyObject* PyCode_GetCode(PyCodeObject *co)
Equivalent to the Python code ``getattr(co, 'co_code')``.
@@ -90,3 +92,28 @@ bound into a function.
.. versionadded:: 3.11
+.. c:function:: PyObject* PyCode_GetVarnames(PyCodeObject *co)
+
+ Equivalent to the Python code ``getattr(co, 'co_varnames')``.
+ Returns a new reference to a :c:type:`PyTupleObject` containing the names of
+ the local variables. On error, ``NULL`` is returned and an exception
+ is raised.
+
+ .. versionadded:: 3.11
+
+.. c:function:: PyObject* PyCode_GetCellvars(PyCodeObject *co)
+
+ Equivalent to the Python code ``getattr(co, 'co_cellvars')``.
+ Returns a new reference to a :c:type:`PyTupleObject` containing the names of
+ the local variables that are referenced by nested functions. On error, ``NULL``
+ is returned and an exception is raised.
+
+ .. versionadded:: 3.11
+
+.. c:function:: PyObject* PyCode_GetFreevars(PyCodeObject *co)
+
+ Equivalent to the Python code ``getattr(co, 'co_freevars')``.
+ Returns a new reference to a :c:type:`PyTupleObject` containing the names of
+ the free variables. On error, ``NULL`` is returned and an exception is raised.
+
+ .. versionadded:: 3.11
diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst
index c25894681bca35..344da903da4c1a 100644
--- a/Doc/c-api/complex.rst
+++ b/Doc/c-api/complex.rst
@@ -5,7 +5,7 @@
Complex Number Objects
----------------------
-.. index:: object: complex number
+.. index:: pair: object; complex number
Python's complex number objects are implemented as two distinct types when
viewed from the C API: one is the Python object exposed to Python programs, and
@@ -115,12 +115,12 @@ Complex Numbers as Python Objects
.. c:function:: double PyComplex_RealAsDouble(PyObject *op)
- Return the real part of *op* as a C :c:type:`double`.
+ Return the real part of *op* as a C :c:expr:`double`.
.. c:function:: double PyComplex_ImagAsDouble(PyObject *op)
- Return the imaginary part of *op* as a C :c:type:`double`.
+ Return the imaginary part of *op* as a C :c:expr:`double`.
.. c:function:: Py_complex PyComplex_AsCComplex(PyObject *op)
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index 8d3124a12fa9d2..880f7b15ce68e8 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -40,7 +40,7 @@ This section describes Python type objects and the singleton object ``None``.
Numeric Objects
===============
-.. index:: object: numeric
+.. index:: pair: object; numeric
.. toctree::
@@ -55,7 +55,7 @@ Numeric Objects
Sequence Objects
================
-.. index:: object: sequence
+.. index:: pair: object; sequence
Generic operations on sequence objects were discussed in the previous chapter;
this section deals with the specific kinds of sequence objects that are
@@ -77,7 +77,7 @@ intrinsic to the Python language.
Container Objects
=================
-.. index:: object: mapping
+.. index:: pair: object; mapping
.. toctree::
diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst
index 7b4cc1cacdd4ab..fdb321fe7ab3f2 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -28,7 +28,8 @@ not.
The wrappers ensure that ``str[size-1]`` is always ``'\0'`` upon return. They
never write more than *size* bytes (including the trailing ``'\0'``) into str.
Both functions require that ``str != NULL``, ``size > 0``, ``format != NULL``
-and ``size < INT_MAX``.
+and ``size < INT_MAX``. Note that this means there is no equivalent to the C99
+``n = snprintf(NULL, 0, ...)`` which would determine the necessary buffer size.
The return value (*rv*) for these functions should be interpreted as follows:
@@ -49,7 +50,7 @@ The following functions provide locale-independent string to number conversions.
.. c:function:: double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)
- Convert a string ``s`` to a :c:type:`double`, raising a Python
+ Convert a string ``s`` to a :c:expr:`double`, raising a Python
exception on failure. The set of accepted strings corresponds to
the set of strings accepted by Python's :func:`float` constructor,
except that ``s`` must not have leading or trailing whitespace.
@@ -83,7 +84,7 @@ The following functions provide locale-independent string to number conversions.
.. c:function:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype)
- Convert a :c:type:`double` *val* to a string using supplied
+ Convert a :c:expr:`double` *val* to a string using supplied
*format_code*, *precision*, and *flags*.
*format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``,
diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst
index 4c4e4bcfa63335..72fc07afbf1f4d 100644
--- a/Doc/c-api/datetime.rst
+++ b/Doc/c-api/datetime.rst
@@ -132,6 +132,7 @@ Macros to create objects:
resulting number of microseconds and seconds lie in the ranges documented for
:class:`datetime.timedelta` objects.
+
.. c:function:: PyObject* PyTimeZone_FromOffset(PyDateTime_DeltaType* offset)
Return a :class:`datetime.timezone` object with an unnamed fixed offset
@@ -139,6 +140,7 @@ Macros to create objects:
.. versionadded:: 3.7
+
.. c:function:: PyObject* PyTimeZone_FromOffsetAndName(PyDateTime_DeltaType* offset, PyUnicode* name)
Return a :class:`datetime.timezone` object with a fixed offset represented
@@ -190,12 +192,21 @@ must not be ``NULL``, and the type is not checked:
Return the microsecond, as an int from 0 through 999999.
+
+.. c:function:: int PyDateTime_DATE_GET_FOLD(PyDateTime_DateTime *o)
+
+ Return the fold, as an int from 0 through 1.
+
+ .. versionadded:: 3.6
+
+
.. c:function:: PyObject* PyDateTime_DATE_GET_TZINFO(PyDateTime_DateTime *o)
Return the tzinfo (which may be ``None``).
.. versionadded:: 3.10
+
Macros to extract fields from time objects. The argument must be an instance of
:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``,
and the type is not checked:
@@ -219,6 +230,14 @@ and the type is not checked:
Return the microsecond, as an int from 0 through 999999.
+
+.. c:function:: int PyDateTime_TIME_GET_FOLD(PyDateTime_Time *o)
+
+ Return the fold, as an int from 0 through 1.
+
+ .. versionadded:: 3.6
+
+
.. c:function:: PyObject* PyDateTime_TIME_GET_TZINFO(PyDateTime_Time *o)
Return the tzinfo (which may be ``None``).
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index d257c9b5f763d1..17cde77c186ff4 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -5,7 +5,7 @@
Dictionary Objects
------------------
-.. index:: object: dictionary
+.. index:: pair: object; dictionary
.. c:type:: PyDictObject
@@ -73,14 +73,14 @@ Dictionary Objects
.. index:: single: PyUnicode_FromString()
Insert *val* into the dictionary *p* using *key* as a key. *key* should
- be a :c:type:`const char*`. The key object is created using
+ be a :c:expr:`const char*`. The key object is created using
``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on
failure. This function *does not* steal a reference to *val*.
.. c:function:: int PyDict_DelItem(PyObject *p, PyObject *key)
- Remove the entry in dictionary *p* with key *key*. *key* must be hashable;
+ Remove the entry in dictionary *p* with key *key*. *key* must be :term:`hashable`;
if it isn't, :exc:`TypeError` is raised.
If *key* is not in the dictionary, :exc:`KeyError` is raised.
Return ``0`` on success or ``-1`` on failure.
@@ -118,7 +118,7 @@ Dictionary Objects
.. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key)
This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a
- :c:type:`const char*`, rather than a :c:type:`PyObject*`.
+ :c:expr:`const char*`, rather than a :c:expr:`PyObject*`.
Note that exceptions which occur while calling :meth:`__hash__` and
:meth:`__eq__` methods and creating a temporary string object
@@ -154,7 +154,7 @@ Dictionary Objects
.. c:function:: Py_ssize_t PyDict_Size(PyObject *p)
- .. index:: builtin: len
+ .. index:: pair: built-in function; len
Return the number of items in the dictionary. This is equivalent to
``len(p)`` on a dictionary.
@@ -167,7 +167,7 @@ Dictionary Objects
prior to the first call to this function to start the iteration; the
function returns true for each pair in the dictionary, and false once all
pairs have been reported. The parameters *pkey* and *pvalue* should either
- point to :c:type:`PyObject*` variables that will be filled in with each key
+ point to :c:expr:`PyObject*` variables that will be filled in with each key
and value, respectively, or may be ``NULL``. Any references returned through
them are borrowed. *ppos* should not be altered during iteration. Its
value represents offsets within the internal dictionary structure, and
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 7bfeca5958cc42..092e548fb8fd83 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -14,7 +14,7 @@ there is a global indicator (per thread) of the last error that occurred. Most
C API functions don't clear this on success, but will set it to indicate the
cause of the error on failure. Most C API functions also return an error
indicator, usually ``NULL`` if they are supposed to return a pointer, or ``-1``
-if they return an integer (exception: the :c:func:`PyArg_\*` functions
+if they return an integer (exception: the ``PyArg_*`` functions
return ``1`` for success and ``0`` for failure).
Concretely, the error indicator consists of three object pointers: the
@@ -189,7 +189,7 @@ For convenience, some of these functions will always return a
.. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr)
This is a convenience function to raise :exc:`WindowsError`. If called with
- *ierr* of :c:data:`0`, the error code returned by a call to :c:func:`GetLastError`
+ *ierr* of ``0``, the error code returned by a call to :c:func:`GetLastError`
is used instead. It calls the Win32 function :c:func:`FormatMessage` to retrieve
the Windows description of error code given by *ierr* or :c:func:`GetLastError`,
then it constructs a tuple object whose first item is the *ierr* value and whose
@@ -370,7 +370,7 @@ Querying the error indicator
.. c:function:: PyObject* PyErr_Occurred()
Test whether the error indicator is set. If set, return the exception *type*
- (the first argument to the last call to one of the :c:func:`PyErr_Set\*`
+ (the first argument to the last call to one of the ``PyErr_Set*``
functions or to :c:func:`PyErr_Restore`). If not set, return ``NULL``. You do not
own a reference to the return value, so you do not need to :c:func:`Py_DECREF`
it.
@@ -543,7 +543,7 @@ Signal Handling
.. c:function:: int PyErr_CheckSignals()
.. index::
- module: signal
+ pair: module; signal
single: SIGINT
single: KeyboardInterrupt (built-in exception)
@@ -574,7 +574,7 @@ Signal Handling
.. c:function:: void PyErr_SetInterrupt()
.. index::
- module: signal
+ pair: module; signal
single: SIGINT
single: KeyboardInterrupt (built-in exception)
@@ -589,7 +589,7 @@ Signal Handling
.. c:function:: int PyErr_SetInterruptEx(int signum)
.. index::
- module: signal
+ pair: module; signal
single: KeyboardInterrupt (built-in exception)
Simulate the effect of a signal arriving. The next time
@@ -848,7 +848,7 @@ Standard Exceptions
All standard Python exceptions are available as global variables whose names are
``PyExc_`` followed by the Python exception name. These have the type
-:c:type:`PyObject*`; they are all class objects. For completeness, here are all
+:c:expr:`PyObject*`; they are all class objects. For completeness, here are all
the variables:
.. index::
@@ -909,11 +909,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` | |
+-----------------------------------------+---------------------------------+----------+
@@ -959,7 +959,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` | |
+-----------------------------------------+---------------------------------+----------+
@@ -971,7 +971,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` | |
+-----------------------------------------+---------------------------------+----------+
@@ -981,7 +981,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` | |
+-----------------------------------------+---------------------------------+----------+
@@ -1046,7 +1046,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
@@ -1054,10 +1054,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.
@@ -1068,7 +1068,7 @@ Standard Warning Categories
All standard Python warning categories are available as global variables whose
names are ``PyExc_`` followed by the Python exception name. These have the type
-:c:type:`PyObject*`; they are all class objects. For completeness, here are all
+:c:expr:`PyObject*`; they are all class objects. For completeness, here are all
the variables:
.. index::
@@ -1087,7 +1087,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` | |
+------------------------------------------+---------------------------------+----------+
@@ -1115,5 +1115,5 @@ the variables:
Notes:
-(1)
+.. [3]
This is a base class for other standard warning categories.
diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst
index ed3735aa83608a..f32ecba9f27029 100644
--- a/Doc/c-api/file.rst
+++ b/Doc/c-api/file.rst
@@ -5,10 +5,10 @@
File Objects
------------
-.. index:: object: file
+.. index:: pair: object; file
These APIs are a minimal emulation of the Python 2 C API for built-in file
-objects, which used to rely on the buffered I/O (:c:type:`FILE*`) support
+objects, which used to rely on the buffered I/O (:c:expr:`FILE*`) support
from the C standard library. In Python 3, files and streams use the new
:mod:`io` module, which defines several layers over the low-level unbuffered
I/O of the operating system. The functions described below are
@@ -38,7 +38,7 @@ the :mod:`io` APIs instead.
.. c:function:: int PyObject_AsFileDescriptor(PyObject *p)
- Return the file descriptor associated with *p* as an :c:type:`int`. If the
+ Return the file descriptor associated with *p* as an :c:expr:`int`. If the
object is an integer, its value is returned. If not, the
object's :meth:`~io.IOBase.fileno` method is called if it exists; the
method must return an integer, which is returned as the file descriptor
@@ -65,7 +65,7 @@ the :mod:`io` APIs instead.
Overrides the normal behavior of :func:`io.open_code` to pass its parameter
through the provided handler.
- The handler is a function of type :c:type:`PyObject *(\*)(PyObject *path,
+ The handler is a function of type :c:expr:`PyObject *(\*)(PyObject *path,
void *userData)`, where *path* is guaranteed to be :c:type:`PyUnicodeObject`.
The *userData* pointer is passed into the hook function. Since hook
diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst
index b306caf74b7c81..05b2d100d575cb 100644
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -5,7 +5,7 @@
Floating Point Objects
----------------------
-.. index:: object: floating point
+.. index:: pair: object; floating point
.. c:type:: PyFloatObject
@@ -44,7 +44,7 @@ Floating Point Objects
.. c:function:: double PyFloat_AsDouble(PyObject *pyfloat)
- Return a C :c:type:`double` representation of the contents of *pyfloat*. If
+ Return a C :c:expr:`double` representation of the contents of *pyfloat*. If
*pyfloat* is not a Python floating point object but has a :meth:`__float__`
method, this method will first be called to convert *pyfloat* into a float.
If ``__float__()`` is not defined then it falls back to :meth:`__index__`.
@@ -57,7 +57,7 @@ Floating Point Objects
.. c:function:: double PyFloat_AS_DOUBLE(PyObject *pyfloat)
- Return a C :c:type:`double` representation of the contents of *pyfloat*, but
+ Return a C :c:expr:`double` representation of the contents of *pyfloat*, but
without error checking.
@@ -70,12 +70,12 @@ Floating Point Objects
.. c:function:: double PyFloat_GetMax()
- Return the maximum representable finite float *DBL_MAX* as C :c:type:`double`.
+ Return the maximum representable finite float *DBL_MAX* as C :c:expr:`double`.
.. c:function:: double PyFloat_GetMin()
- Return the minimum normalized positive float *DBL_MIN* as C :c:type:`double`.
+ Return the minimum normalized positive float *DBL_MIN* as C :c:expr:`double`.
Pack and Unpack functions
@@ -83,8 +83,8 @@ Pack and Unpack functions
The pack and unpack functions provide an efficient platform-independent way to
store floating-point values as byte strings. The Pack routines produce a bytes
-string from a C :c:type:`double`, and the Unpack routines produce a C
-:c:type:`double` from such a bytes string. The suffix (2, 4 or 8) specifies the
+string from a C :c:expr:`double`, and the Unpack routines produce a C
+:c:expr:`double` from such a bytes string. The suffix (2, 4 or 8) specifies the
number of bytes in the bytes string.
On platforms that appear to use IEEE 754 formats these functions work by
@@ -107,7 +107,7 @@ Pack functions
--------------
The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an
-:c:type:`int` argument, non-zero if you want the bytes string in little-endian
+:c:expr:`int` argument, non-zero if you want the bytes string in little-endian
format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you
want big-endian format (exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN`
constant can be used to use the native endian: it is equal to ``1`` on big
@@ -138,7 +138,7 @@ Unpack functions
----------------
The unpack routines read 2, 4 or 8 bytes, starting at *p*. *le* is an
-:c:type:`int` argument, non-zero if the bytes string is in little-endian format
+:c:expr:`int` argument, non-zero if the bytes string is in little-endian format
(exponent last, at ``p+1``, ``p+3`` or ``p+6`` and ``p+7``), zero if big-endian
(exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` constant can be used to
use the native endian: it is equal to ``1`` on big endian processor, or ``0``
diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst
index 46ce700abf1474..b52f3477ee2316 100644
--- a/Doc/c-api/frame.rst
+++ b/Doc/c-api/frame.rst
@@ -19,6 +19,24 @@ can be used to get a frame object.
See also :ref:`Reflection `.
+.. c:var:: PyTypeObject PyFrame_Type
+
+ The type of frame objects.
+ It is the same object as :py:class:`types.FrameType` in the Python layer.
+
+ .. versionchanged:: 3.11
+
+ Previously, this type was only available after including
+ ````.
+
+.. c:function:: int PyFrame_Check(PyObject *obj)
+
+ Return non-zero if *obj* is a frame object.
+
+ .. versionchanged:: 3.11
+
+ Previously, this function was only available after including
+ ````.
.. c:function:: PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst
index 56c18396d3221d..1f28a685978b56 100644
--- a/Doc/c-api/function.rst
+++ b/Doc/c-api/function.rst
@@ -5,7 +5,7 @@
Function Objects
----------------
-.. index:: object: function
+.. index:: pair: object; function
There are a few functions specific to Python functions.
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index 5e2333a74ce648..57328fc16198c5 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -41,7 +41,7 @@ Importing Modules
.. c:function:: PyObject* PyImport_ImportModuleEx(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
- .. index:: builtin: __import__
+ .. index:: pair: built-in function; __import__
Import a module. This is best described by referring to the built-in Python
function :func:`__import__`.
@@ -120,7 +120,7 @@ Importing Modules
.. c:function:: PyObject* PyImport_ExecCodeModule(const char *name, PyObject *co)
- .. index:: builtin: compile
+ .. index:: pair: built-in function; compile
Given a module name (possibly of the form ``package.module``) and a code object
read from a Python bytecode file or obtained from the built-in function
@@ -243,7 +243,7 @@ Importing Modules
UTF-8 encoded string instead of a Unicode object.
-.. c:type:: struct _frozen
+.. c:struct:: _frozen
.. index:: single: freeze utility
@@ -265,7 +265,7 @@ Importing Modules
.. c:var:: const struct _frozen* PyImport_FrozenModules
- This pointer is initialized to point to an array of :c:type:`struct _frozen`
+ This pointer is initialized to point to an array of :c:struct:`_frozen`
records, terminated by one whose members are all ``NULL`` or zero. When a frozen
module is imported, it is searched in this table. Third-party code could play
tricks with this to provide a dynamically created collection of frozen modules.
@@ -281,7 +281,7 @@ Importing Modules
:c:func:`Py_Initialize`.
-.. c:type:: struct _inittab
+.. c:struct:: _inittab
Structure describing a single entry in the list of built-in modules. Each of
these structures gives the name and initialization function for a module built
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index d4954958f855f5..dda87f4e31a426 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -233,9 +233,9 @@ Initializing and finalizing the interpreter
single: PyEval_InitThreads()
single: modules (in module sys)
single: path (in module sys)
- module: builtins
- module: __main__
- module: sys
+ pair: module; builtins
+ pair: module; __main__
+ pair: module; sys
triple: module; search; path
single: PySys_SetArgv()
single: PySys_SetArgvEx()
@@ -376,7 +376,7 @@ Process-wide parameters
interpreter will change the contents of this storage.
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
- :c:type:`wchar_*` string.
+ :c:expr:`wchar_*` string.
.. deprecated:: 3.11
@@ -404,7 +404,7 @@ Process-wide parameters
program name is ``'/usr/local/bin/python'``, the prefix is ``'/usr/local'``. The
returned string points into static storage; the caller should not modify its
value. This corresponds to the :makevar:`prefix` variable in the top-level
- :file:`Makefile` and the ``--prefix`` argument to the :program:`configure`
+ :file:`Makefile` and the :option:`--prefix` argument to the :program:`configure`
script at build time. The value is available to Python code as ``sys.prefix``.
It is only useful on Unix. See also the next function.
@@ -527,7 +527,7 @@ Process-wide parameters
if required after calling :c:func:`Py_Initialize`.
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
- :c:type:`wchar_*` string.
+ :c:expr:`wchar_*` string.
The path argument is copied internally, so the caller may free it after the
call completes.
@@ -642,7 +642,7 @@ Process-wide parameters
directory (``"."``).
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
- :c:type:`wchar_*` string.
+ :c:expr:`wchar_*` string.
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
members of the :ref:`Python Initialization Configuration `.
@@ -678,7 +678,7 @@ Process-wide parameters
:option:`-I`.
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
- :c:type:`wchar_*` string.
+ :c:expr:`wchar_*` string.
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
members of the :ref:`Python Initialization Configuration `.
@@ -704,12 +704,12 @@ Process-wide parameters
this storage.
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
- :c:type:`wchar_*` string.
+ :c:expr:`wchar_*` string.
.. deprecated:: 3.11
-.. c:function:: w_char* Py_GetPythonHome()
+.. c:function:: wchar_t* Py_GetPythonHome()
Return the default "home", that is, the value set by a previous call to
:c:func:`Py_SetPythonHome`, or the value of the :envvar:`PYTHONHOME`
@@ -847,11 +847,11 @@ from a C thread is::
/* Release the thread. No Python API allowed beyond this point. */
PyGILState_Release(gstate);
-Note that the :c:func:`PyGILState_\*` functions assume there is only one global
+Note that the ``PyGILState_*`` functions assume there is only one global
interpreter (created automatically by :c:func:`Py_Initialize`). Python
supports the creation of additional interpreters (using
:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
-:c:func:`PyGILState_\*` API is unsupported.
+``PyGILState_*`` API is unsupported.
.. _fork-and-threads:
@@ -914,7 +914,7 @@ code, or when embedding the Python interpreter:
.. c:type:: PyThreadState
This data structure represents the state of a single thread. The only public
- data member is :attr:`interp` (:c:type:`PyInterpreterState *`), which points to
+ data member is :attr:`interp` (:c:expr:`PyInterpreterState *`), which points to
this thread's interpreter state.
@@ -940,9 +940,9 @@ code, or when embedding the Python interpreter:
.. versionchanged:: 3.2
This function cannot be called before :c:func:`Py_Initialize()` anymore.
- .. deprecated-removed:: 3.9 3.11
+ .. deprecated:: 3.9
- .. index:: module: _thread
+ .. index:: pair: module; _thread
.. c:function:: int PyEval_ThreadsInitialized()
@@ -954,7 +954,7 @@ code, or when embedding the Python interpreter:
.. versionchanged:: 3.7
The :term:`GIL` is now initialized by :c:func:`Py_Initialize()`.
- .. deprecated-removed:: 3.9 3.11
+ .. deprecated:: 3.9
.. c:function:: PyThreadState* PyEval_SaveThread()
@@ -1291,8 +1291,8 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
exception (if any) for the thread is cleared. This raises no exceptions.
.. versionchanged:: 3.7
- The type of the *id* parameter changed from :c:type:`long` to
- :c:type:`unsigned long`.
+ The type of the *id* parameter changed from :c:expr:`long` to
+ :c:expr:`unsigned long`.
.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate)
@@ -1385,9 +1385,9 @@ function. You can create and destroy them using the following functions:
.. c:function:: PyThreadState* Py_NewInterpreter()
.. index::
- module: builtins
- module: __main__
- module: sys
+ pair: module; builtins
+ pair: module; __main__
+ pair: module; sys
single: stdout (in module sys)
single: stderr (in module sys)
single: stdin (in module sys)
@@ -1478,7 +1478,7 @@ operations executed by such objects may affect the wrong (sub-)interpreter's
dictionary of loaded modules. It is equally important to avoid sharing
objects from which the above are reachable.
-Also note that combining this functionality with :c:func:`PyGILState_\*` APIs
+Also note that combining this functionality with ``PyGILState_*`` APIs
is delicate, because these APIs assume a bijection between Python thread states
and OS-level threads, an assumption broken by the presence of sub-interpreters.
It is highly recommended that you don't switch sub-interpreters between a pair
@@ -1730,7 +1730,7 @@ The Python interpreter provides low-level support for thread-local storage
(TLS) which wraps the underlying native TLS implementation to support the
Python-level thread local storage API (:class:`threading.local`). The
CPython C level APIs are similar to those offered by pthreads and Windows:
-use a thread key and functions to associate a :c:type:`void*` value per
+use a thread key and functions to associate a :c:expr:`void*` value per
thread.
The GIL does *not* need to be held when calling these functions; they supply
@@ -1741,8 +1741,8 @@ you need to include :file:`pythread.h` to use thread-local storage.
.. note::
None of these API functions handle memory management on behalf of the
- :c:type:`void*` values. You need to allocate and deallocate them yourself.
- If the :c:type:`void*` values happen to be :c:type:`PyObject*`, these
+ :c:expr:`void*` values. You need to allocate and deallocate them yourself.
+ If the :c:expr:`void*` values happen to be :c:expr:`PyObject*`, these
functions don't do refcount operations on them either.
.. _thread-specific-storage-api:
@@ -1752,7 +1752,7 @@ Thread Specific Storage (TSS) API
TSS API is introduced to supersede the use of the existing TLS API within the
CPython interpreter. This API uses a new type :c:type:`Py_tss_t` instead of
-:c:type:`int` to represent thread keys.
+:c:expr:`int` to represent thread keys.
.. versionadded:: 3.7
@@ -1796,11 +1796,11 @@ is not possible due to its implementation being opaque at build time.
Free the given *key* allocated by :c:func:`PyThread_tss_alloc`, after
first calling :c:func:`PyThread_tss_delete` to ensure any associated
thread locals have been unassigned. This is a no-op if the *key*
- argument is `NULL`.
+ argument is ``NULL``.
.. note::
A freed key becomes a dangling pointer. You should reset the key to
- `NULL`.
+ ``NULL``.
Methods
@@ -1838,14 +1838,14 @@ undefined if the given :c:type:`Py_tss_t` has not been initialized by
.. c:function:: int PyThread_tss_set(Py_tss_t *key, void *value)
- Return a zero value to indicate successfully associating a :c:type:`void*`
+ Return a zero value to indicate successfully associating a :c:expr:`void*`
value with a TSS key in the current thread. Each thread has a distinct
- mapping of the key to a :c:type:`void*` value.
+ mapping of the key to a :c:expr:`void*` value.
.. c:function:: void* PyThread_tss_get(Py_tss_t *key)
- Return the :c:type:`void*` value associated with a TSS key in the current
+ Return the :c:expr:`void*` value associated with a TSS key in the current
thread. This returns ``NULL`` if no value is associated with the key in the
current thread.
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index 728df2100336e7..24d66201f68dbb 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -97,7 +97,7 @@ PyWideStringList
If *index* is greater than or equal to *list* length, append *item* to
*list*.
- *index* must be greater than or equal to 0.
+ *index* must be greater than or equal to ``0``.
Python must be preinitialized to call this function.
@@ -254,10 +254,10 @@ PyPreConfig
.. c:member:: int configure_locale
- Set the LC_CTYPE locale to the user preferred locale?
+ Set the LC_CTYPE locale to the user preferred locale.
- If equals to 0, set :c:member:`~PyPreConfig.coerce_c_locale` and
- :c:member:`~PyPreConfig.coerce_c_locale_warn` members to 0.
+ If equals to ``0``, set :c:member:`~PyPreConfig.coerce_c_locale` and
+ :c:member:`~PyPreConfig.coerce_c_locale_warn` members to ``0``.
See the :term:`locale encoding`.
@@ -265,9 +265,9 @@ PyPreConfig
.. c:member:: int coerce_c_locale
- If equals to 2, coerce the C locale.
+ If equals to ``2``, coerce the C locale.
- If equals to 1, read the LC_CTYPE locale to decide if it should be
+ If equals to ``1``, read the LC_CTYPE locale to decide if it should be
coerced.
See the :term:`locale encoding`.
@@ -282,8 +282,8 @@ PyPreConfig
.. c:member:: int dev_mode
- If non-zero, enables the :ref:`Python Development Mode `:
- see :c:member:`PyConfig.dev_mode`.
+ :ref:`Python Development Mode `: see
+ :c:member:`PyConfig.dev_mode`.
Default: ``-1`` in Python mode, ``0`` in isolated mode.
@@ -329,8 +329,10 @@ PyPreConfig
If non-zero, enable the :ref:`Python UTF-8 Mode `.
- Set by the :option:`-X utf8 <-X>` command line option and the
- :envvar:`PYTHONUTF8` environment variable.
+ Set to ``0`` or ``1`` by the :option:`-X utf8 <-X>` command line option
+ and the :envvar:`PYTHONUTF8` environment variable.
+
+ Also set to ``1`` if the ``LC_CTYPE`` locale is ``C`` or ``POSIX``.
Default: ``-1`` in Python config and ``0`` in isolated config.
@@ -555,7 +557,7 @@ PyConfig
* Otherwise (``python -c code`` and ``python``), prepend an empty string,
which means the current working directory.
- Set to 1 by the :option:`-P` command line option and the
+ Set to ``1`` by the :option:`-P` command line option and the
:envvar:`PYTHONSAFEPATH` environment variable.
Default: ``0`` in Python config, ``1`` in isolated config.
@@ -592,10 +594,10 @@ PyConfig
.. c:member:: int buffered_stdio
- If equals to 0 and :c:member:`~PyConfig.configure_c_stdio` is non-zero,
+ If equals to ``0`` and :c:member:`~PyConfig.configure_c_stdio` is non-zero,
disable buffering on the C streams stdout and stderr.
- Set to 0 by the :option:`-u` command line option and the
+ Set to ``0`` by the :option:`-u` command line option and the
:envvar:`PYTHONUNBUFFERED` environment variable.
stdin is always opened in buffered mode.
@@ -604,11 +606,11 @@ PyConfig
.. c:member:: int bytes_warning
- If equals to 1, issue a warning when comparing :class:`bytes` or
+ If equals to ``1``, issue a warning when comparing :class:`bytes` or
:class:`bytearray` with :class:`str`, or comparing :class:`bytes` with
:class:`int`.
- If equal or greater to 2, raise a :exc:`BytesWarning` exception in these
+ If equal or greater to ``2``, raise a :exc:`BytesWarning` exception in these
cases.
Incremented by the :option:`-b` command line option.
@@ -671,6 +673,9 @@ PyConfig
If non-zero, enable the :ref:`Python Development Mode `.
+ Set to ``1`` by the :option:`-X dev <-X>` option and the
+ :envvar:`PYTHONDEVMODE` environment variable.
+
Default: ``-1`` in Python mode, ``0`` in isolated mode.
.. c:member:: int dump_refs
@@ -730,9 +735,8 @@ 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.
@@ -800,7 +804,7 @@ PyConfig
Enter interactive mode after executing a script or a command.
- If greater than 0, enable inspect: when a script is passed as first
+ If greater than ``0``, enable inspect: when a script is passed as first
argument or the -c option is used, enter interactive mode after executing
the script or the command, even when :data:`sys.stdin` does not appear to
be a terminal.
@@ -818,7 +822,7 @@ PyConfig
.. c:member:: int interactive
- If greater than 0, enable the interactive mode (REPL).
+ If greater than ``0``, enable the interactive mode (REPL).
Incremented by the :option:`-i` command line option.
@@ -826,17 +830,19 @@ PyConfig
.. c:member:: int isolated
- If greater than 0, enable isolated mode:
+ If greater than ``0``, enable isolated mode:
- * Set :c:member:`~PyConfig.safe_path` to 1:
+ * Set :c:member:`~PyConfig.safe_path` to ``1``:
don't prepend a potentially unsafe path to :data:`sys.path` at Python
startup.
- * Set :c:member:`~PyConfig.use_environment` to 0.
- * Set :c:member:`~PyConfig.user_site_directory` to 0: don't add the user
+ * Set :c:member:`~PyConfig.use_environment` to ``0``.
+ * Set :c:member:`~PyConfig.user_site_directory` to ``0``: don't add the user
site directory to :data:`sys.path`.
* Python REPL doesn't import :mod:`readline` nor enable default readline
configuration on interactive prompts.
+ Set to ``1`` by the :option:`-I` command line option.
+
Default: ``0`` in Python mode, ``1`` in isolated mode.
See also :c:member:`PyPreConfig.isolated`.
@@ -906,7 +912,7 @@ PyConfig
Module search paths: :data:`sys.path`.
- If :c:member:`~PyConfig.module_search_paths_set` is equal to 0,
+ If :c:member:`~PyConfig.module_search_paths_set` is equal to ``0``,
:c:func:`Py_InitializeFromConfig` will replace
:c:member:`~PyConfig.module_search_paths` and sets
:c:member:`~PyConfig.module_search_paths_set` to ``1``.
@@ -970,7 +976,7 @@ PyConfig
.. c:member:: int parser_debug
- Parser debug mode. If greater than 0, turn on parser debugging output (for expert only, depending
+ Parser debug mode. If greater than ``0``, turn on parser debugging output (for expert only, depending
on compilation options).
Incremented by the :option:`-d` command line option. Set to the
@@ -981,7 +987,7 @@ PyConfig
.. c:member:: int pathconfig_warnings
If non-zero, calculation of path configuration is allowed to log
- warnings into ``stderr``. If equals to 0, suppress these warnings.
+ warnings into ``stderr``. If equals to ``0``, suppress these warnings.
Default: ``1`` in Python mode, ``0`` in isolated mode.
@@ -1031,7 +1037,7 @@ PyConfig
.. c:member:: int quiet
- Quiet mode. If greater than 0, don't display the copyright and version at
+ Quiet mode. If greater than ``0``, don't display the copyright and version at
Python startup in interactive mode.
Incremented by the :option:`-q` command line option.
@@ -1071,7 +1077,7 @@ PyConfig
Show total reference count at exit?
- Set to 1 by :option:`-X showrefcount <-X>` command line option.
+ Set to ``1`` by :option:`-X showrefcount <-X>` command line option.
Need a :ref:`debug build of Python ` (the ``Py_REF_DEBUG``
macro must be defined).
@@ -1150,6 +1156,8 @@ PyConfig
If equals to zero, ignore the :ref:`environment variables
`.
+ Set to ``0`` by the :option:`-E` environment variable.
+
Default: ``1`` in Python config and ``0`` in isolated config.
.. c:member:: int user_site_directory
@@ -1164,11 +1172,11 @@ PyConfig
.. c:member:: int verbose
- Verbose mode. If greater than 0, print a message each time a module is
+ Verbose mode. If greater than ``0``, print a message each time a module is
imported, showing the place (filename or built-in module) from which
it is loaded.
- If greater or equal to 2, print a message for each file that is checked
+ If greater or equal to ``2``, print a message for each file that is checked
for when searching for a module. Also provides information on module
cleanup at exit.
@@ -1199,7 +1207,7 @@ PyConfig
.. c:member:: int write_bytecode
- If equal to 0, Python won't try to write ``.pyc`` files on the import of
+ If equal to ``0``, Python won't try to write ``.pyc`` files on the import of
source modules.
Set to ``0`` by the :option:`-B` command line option and the
@@ -1280,7 +1288,11 @@ Example setting the program name::
}
More complete example modifying the default configuration, read the
-configuration, and then override some parameters::
+configuration, and then override some parameters. Note that since
+3.11, many parameters are not calculated until initialization, and
+so values cannot be read from the configuration structure. Any values
+set before initialize is called will be left unchanged by
+initialization::
PyStatus init_python(const char *program_name)
{
@@ -1305,7 +1317,15 @@ configuration, and then override some parameters::
goto done;
}
- /* Append our custom search path to sys.path */
+ /* Specify sys.path explicitly */
+ /* If you want to modify the default set of paths, finish
+ initialization first and then use PySys_GetObject("path") */
+ config.module_search_paths_set = 1;
+ status = PyWideStringList_Append(&config.module_search_paths,
+ L"/path/to/stdlib");
+ if (PyStatus_Exception(status)) {
+ goto done;
+ }
status = PyWideStringList_Append(&config.module_search_paths,
L"/path/to/more/modules");
if (PyStatus_Exception(status)) {
@@ -1400,18 +1420,18 @@ Python Path Configuration
If at least one "output field" is not set, Python calculates the path
configuration to fill unset fields. If
-:c:member:`~PyConfig.module_search_paths_set` is equal to 0,
+:c:member:`~PyConfig.module_search_paths_set` is equal to ``0``,
:c:member:`~PyConfig.module_search_paths` is overridden and
-:c:member:`~PyConfig.module_search_paths_set` is set to 1.
+:c:member:`~PyConfig.module_search_paths_set` is set to ``1``.
It is possible to completely ignore the function calculating the default
path configuration by setting explicitly all path configuration output
fields listed above. A string is considered as set even if it is non-empty.
``module_search_paths`` is considered as set if
-``module_search_paths_set`` is set to 1. In this case, path
-configuration input fields are ignored as well.
+``module_search_paths_set`` is set to ``1``. In this case,
+``module_search_paths`` will be used without modification.
-Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when
+Set :c:member:`~PyConfig.pathconfig_warnings` to ``0`` to suppress warnings when
calculating the path configuration (Unix only, Windows does not log any warning).
If :c:member:`~PyConfig.base_prefix` or :c:member:`~PyConfig.base_exec_prefix`
@@ -1445,10 +1465,10 @@ The following configuration files are used by the path configuration:
If a ``._pth`` file is present:
-* Set :c:member:`~PyConfig.isolated` to 1.
-* Set :c:member:`~PyConfig.use_environment` to 0.
-* Set :c:member:`~PyConfig.site_import` to 0.
-* Set :c:member:`~PyConfig.safe_path` to 1.
+* Set :c:member:`~PyConfig.isolated` to ``1``.
+* Set :c:member:`~PyConfig.use_environment` to ``0``.
+* Set :c:member:`~PyConfig.site_import` to ``0``.
+* Set :c:member:`~PyConfig.safe_path` to ``1``.
The ``__PYVENV_LAUNCHER__`` environment variable is used to set
:c:member:`PyConfig.base_executable`
@@ -1511,7 +1531,7 @@ initialization, the core feature of :pep:`432`:
Private provisional API:
-* :c:member:`PyConfig._init_main`: if set to 0,
+* :c:member:`PyConfig._init_main`: if set to ``0``,
:c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase.
* :c:member:`PyConfig._isolated_interpreter`: if non-zero,
disallow threads, subprocesses and fork.
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index 9efac0b83d024d..17710b02abbc4e 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -78,19 +78,19 @@ used by extension writers. Structure member names do not have a reserved prefix.
The header files are typically installed with Python. On Unix, these are
located in the directories :file:`{prefix}/include/pythonversion/` and
-:file:`{exec_prefix}/include/pythonversion/`, where :envvar:`prefix` and
-:envvar:`exec_prefix` are defined by the corresponding parameters to Python's
+:file:`{exec_prefix}/include/pythonversion/`, where :option:`prefix <--prefix>` and
+:option:`exec_prefix <--exec-prefix>` are defined by the corresponding parameters to Python's
:program:`configure` script and *version* is
``'%d.%d' % sys.version_info[:2]``. On Windows, the headers are installed
-in :file:`{prefix}/include`, where :envvar:`prefix` is the installation
+in :file:`{prefix}/include`, where ``prefix`` is the installation
directory specified to the installer.
To include the headers, place both directories (if different) on your compiler's
search path for includes. Do *not* place the parent directories on the search
path and then use ``#include ``; this will break on
multi-platform builds since the platform independent headers under
-:envvar:`prefix` include the platform specific headers from
-:envvar:`exec_prefix`.
+:option:`prefix <--prefix>` include the platform specific headers from
+:option:`exec_prefix <--exec-prefix>`.
C++ users should note that although the API is defined entirely using C, the
header files properly declare the entry points to be ``extern "C"``. As a result,
@@ -261,16 +261,16 @@ complete listing.
Objects, Types and Reference Counts
===================================
-.. index:: object: type
+.. index:: pair: object; type
Most Python/C API functions have one or more arguments as well as a return value
-of type :c:type:`PyObject*`. This type is a pointer to an opaque data type
+of type :c:expr:`PyObject*`. This type is a pointer to an opaque data type
representing an arbitrary Python object. Since all Python object types are
treated the same way by the Python language in most situations (e.g.,
assignments, scope rules, and argument passing), it is only fitting that they
should be represented by a single C type. Almost all Python objects live on the
heap: you never declare an automatic or static variable of type
-:c:type:`PyObject`, only pointer variables of type :c:type:`PyObject*` can be
+:c:type:`PyObject`, only pointer variables of type :c:expr:`PyObject*` can be
declared. The sole exception are the type objects; since these must never be
deallocated, they are typically static :c:type:`PyTypeObject` objects.
@@ -530,13 +530,20 @@ Types
-----
There are few other data types that play a significant role in the Python/C
-API; most are simple C types such as :c:type:`int`, :c:type:`long`,
-:c:type:`double` and :c:type:`char*`. A few structure types are used to
+API; most are simple C types such as :c:expr:`int`, :c:expr:`long`,
+:c:expr:`double` and :c:expr:`char*`. A few structure types are used to
describe static tables used to list the functions exported by a module or the
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:
@@ -698,9 +705,9 @@ interpreter can only be used after the interpreter has been initialized.
.. index::
single: Py_Initialize()
- module: builtins
- module: __main__
- module: sys
+ pair: module; builtins
+ pair: module; __main__
+ pair: module; sys
triple: module; search; path
single: path (in module sys)
@@ -772,7 +779,7 @@ A full list of the various types of debugging builds is in the file
:file:`Misc/SpecialBuilds.txt` in the Python source distribution. Builds are
available that support tracing of reference counts, debugging the memory
allocator, or low-level profiling of the main interpreter loop. Only the most
-frequently-used builds will be described in the remainder of this section.
+frequently used builds will be described in the remainder of this section.
Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces
what is generally meant by :ref:`a debug build of Python `.
diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst
index f9e65354a259f4..dbf35611eccd3e 100644
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -5,7 +5,7 @@
List Objects
------------
-.. index:: object: list
+.. index:: pair: object; list
.. c:type:: PyListObject
@@ -45,7 +45,7 @@ List Objects
.. c:function:: Py_ssize_t PyList_Size(PyObject *list)
- .. index:: builtin: len
+ .. index:: pair: built-in function; len
Return the length of the list object in *list*; this is equivalent to
``len(list)`` on a list object.
@@ -138,7 +138,7 @@ List Objects
.. c:function:: PyObject* PyList_AsTuple(PyObject *list)
- .. index:: builtin: tuple
+ .. index:: pair: built-in function; tuple
Return a new tuple object containing the contents of *list*; equivalent to
``tuple(list)``.
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 620344e71373b2..7b0d55dac8798b 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -5,8 +5,8 @@
Integer Objects
---------------
-.. index:: object: long integer
- object: integer
+.. index:: pair: object; long integer
+ pair: object; integer
All integers are implemented as "long" integer objects of arbitrary size.
@@ -47,7 +47,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: PyObject* PyLong_FromUnsignedLong(unsigned long v)
- Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long`, or
+ Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long`, or
``NULL`` on failure.
@@ -65,13 +65,13 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: PyObject* PyLong_FromLongLong(long long v)
- Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or ``NULL``
+ Return a new :c:type:`PyLongObject` object from a C :c:expr:`long long`, or ``NULL``
on failure.
.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v)
- Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long long`,
+ Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long long`,
or ``NULL`` on failure.
@@ -93,6 +93,10 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
underscores after a base specifier and between digits are ignored. If there
are no digits, :exc:`ValueError` will be raised.
+ .. seealso:: Python methods :meth:`int.to_bytes` and :meth:`int.from_bytes`
+ to convert a :c:type:`PyLongObject` to/from an array of bytes in base
+ ``256``. You can call those from C using :c:func:`PyObject_CallMethod`.
+
.. c:function:: PyObject* PyLong_FromUnicodeObject(PyObject *u, int base)
@@ -115,12 +119,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
single: LONG_MAX
single: OverflowError (built-in exception)
- Return a C :c:type:`long` representation of *obj*. If *obj* is not an
+ Return a C :c:expr:`long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
(if present) to convert it to a :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
- :c:type:`long`.
+ :c:expr:`long`.
Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
@@ -133,7 +137,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow)
- Return a C :c:type:`long` representation of *obj*. If *obj* is not an
+ Return a C :c:expr:`long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__`
method (if present) to convert it to a :c:type:`PyLongObject`.
@@ -156,12 +160,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. index::
single: OverflowError (built-in exception)
- Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
+ Return a C :c:expr:`long long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
(if present) to convert it to a :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
- :c:type:`long long`.
+ :c:expr:`long long`.
Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
@@ -174,7 +178,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: long long PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow)
- Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
+ Return a C :c:expr:`long long` representation of *obj*. If *obj* is not an
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
(if present) to convert it to a :c:type:`PyLongObject`.
@@ -215,11 +219,11 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
single: ULONG_MAX
single: OverflowError (built-in exception)
- Return a C :c:type:`unsigned long` representation of *pylong*. *pylong*
+ Return a C :c:expr:`unsigned long` representation of *pylong*. *pylong*
must be an instance of :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
- :c:type:`unsigned long`.
+ :c:expr:`unsigned long`.
Returns ``(unsigned long)-1`` on error.
Use :c:func:`PyErr_Occurred` to disambiguate.
@@ -246,11 +250,11 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. index::
single: OverflowError (built-in exception)
- Return a C :c:type:`unsigned long long` representation of *pylong*. *pylong*
+ Return a C :c:expr:`unsigned long long` representation of *pylong*. *pylong*
must be an instance of :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *pylong* is out of range for an
- :c:type:`unsigned long long`.
+ :c:expr:`unsigned long long`.
Returns ``(unsigned long long)-1`` on error.
Use :c:func:`PyErr_Occurred` to disambiguate.
@@ -261,11 +265,11 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: unsigned long PyLong_AsUnsignedLongMask(PyObject *obj)
- Return a C :c:type:`unsigned long` representation of *obj*. If *obj* is not
+ Return a C :c:expr:`unsigned long` representation of *obj*. If *obj* is not
an instance of :c:type:`PyLongObject`, first call its :meth:`__index__`
method (if present) to convert it to a :c:type:`PyLongObject`.
- If the value of *obj* is out of range for an :c:type:`unsigned long`,
+ If the value of *obj* is out of range for an :c:expr:`unsigned long`,
return the reduction of that value modulo ``ULONG_MAX + 1``.
Returns ``(unsigned long)-1`` on error. Use :c:func:`PyErr_Occurred` to
@@ -280,12 +284,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj)
- Return a C :c:type:`unsigned long long` representation of *obj*. If *obj*
+ Return a C :c:expr:`unsigned long long` representation of *obj*. If *obj*
is not an instance of :c:type:`PyLongObject`, first call its
:meth:`__index__` method (if present) to convert it to a
:c:type:`PyLongObject`.
- If the value of *obj* is out of range for an :c:type:`unsigned long long`,
+ If the value of *obj* is out of range for an :c:expr:`unsigned long long`,
return the reduction of that value modulo ``ULLONG_MAX + 1``.
Returns ``(unsigned long long)-1`` on error. Use :c:func:`PyErr_Occurred`
@@ -300,20 +304,20 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: double PyLong_AsDouble(PyObject *pylong)
- Return a C :c:type:`double` representation of *pylong*. *pylong* must be
+ Return a C :c:expr:`double` representation of *pylong*. *pylong* must be
an instance of :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
- :c:type:`double`.
+ :c:expr:`double`.
Returns ``-1.0`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: void* PyLong_AsVoidPtr(PyObject *pylong)
- Convert a Python integer *pylong* to a C :c:type:`void` pointer.
+ Convert a Python integer *pylong* to a C :c:expr:`void` pointer.
If *pylong* cannot be converted, an :exc:`OverflowError` will be raised. This
- is only assured to produce a usable :c:type:`void` pointer for values created
+ is only assured to produce a usable :c:expr:`void` pointer for values created
with :c:func:`PyLong_FromVoidPtr`.
Returns ``NULL`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst
index 3c9d282c6d0ab0..cffb0ed50fb77d 100644
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -20,7 +20,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
Py_ssize_t PyMapping_Length(PyObject *o)
- .. index:: builtin: len
+ .. index:: pair: built-in function; len
Returns the number of keys in object *o* on success, and ``-1`` on failure.
This is equivalent to the Python expression ``len(o)``.
diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst
index 7bb0dad2b6b6d5..8e25968c6909fd 100644
--- a/Doc/c-api/marshal.rst
+++ b/Doc/c-api/marshal.rst
@@ -21,9 +21,9 @@ unmarshalling. Version 2 uses a binary format for floating point numbers.
.. c:function:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
- Marshal a :c:type:`long` integer, *value*, to *file*. This will only write
+ Marshal a :c:expr:`long` integer, *value*, to *file*. This will only write
the least-significant 32 bits of *value*; regardless of the size of the
- native :c:type:`long` type. *version* indicates the file format.
+ native :c:expr:`long` type. *version* indicates the file format.
.. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)
@@ -43,9 +43,9 @@ The following functions allow marshalled values to be read back in.
.. c:function:: long PyMarshal_ReadLongFromFile(FILE *file)
- Return a C :c:type:`long` from the data stream in a :c:type:`FILE*` opened
+ Return a C :c:expr:`long` from the data stream in a :c:expr:`FILE*` opened
for reading. Only a 32-bit value can be read in using this function,
- regardless of the native size of :c:type:`long`.
+ regardless of the native size of :c:expr:`long`.
On error, sets the appropriate exception (:exc:`EOFError`) and returns
``-1``.
@@ -53,9 +53,9 @@ The following functions allow marshalled values to be read back in.
.. c:function:: int PyMarshal_ReadShortFromFile(FILE *file)
- Return a C :c:type:`short` from the data stream in a :c:type:`FILE*` opened
+ Return a C :c:expr:`short` from the data stream in a :c:expr:`FILE*` opened
for reading. Only a 16-bit value can be read in using this function,
- regardless of the native size of :c:type:`short`.
+ regardless of the native size of :c:expr:`short`.
On error, sets the appropriate exception (:exc:`EOFError`) and returns
``-1``.
@@ -63,7 +63,7 @@ The following functions allow marshalled values to be read back in.
.. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file)
- Return a Python object from the data stream in a :c:type:`FILE*` opened for
+ Return a Python object from the data stream in a :c:expr:`FILE*` opened for
reading.
On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
@@ -72,7 +72,7 @@ The following functions allow marshalled values to be read back in.
.. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file)
- Return a Python object from the data stream in a :c:type:`FILE*` opened for
+ Return a Python object from the data stream in a :c:expr:`FILE*` opened for
reading. Unlike :c:func:`PyMarshal_ReadObjectFromFile`, this function
assumes that no further objects will be read from the file, allowing it to
aggressively load file data into memory so that the de-serialization can
diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst
index 987dea40dd674e..7041c15d23fb83 100644
--- a/Doc/c-api/memory.rst
+++ b/Doc/c-api/memory.rst
@@ -75,7 +75,7 @@ memory manager. For example, this is required when the interpreter is extended
with new object types written in C. Another reason for using the Python heap is
the desire to *inform* the Python memory manager about the memory needs of the
extension module. Even when the requested memory is used exclusively for
-internal, highly-specific purposes, delegating all memory requests to the Python
+internal, highly specific purposes, delegating all memory requests to the Python
memory manager causes the interpreter to have a more accurate image of its
memory footprint as a whole. Consequently, under certain circumstances, the
Python memory manager may or may not trigger appropriate actions, like garbage
@@ -95,6 +95,8 @@ for the I/O buffer escapes completely the Python memory manager.
Allocator Domains
=================
+.. _allocator-domains:
+
All allocating functions belong to one of three different "domains" (see also
:c:type:`PyMemAllocatorDomain`). These domains represent different allocation
strategies and are optimized for different purposes. The specific details on
@@ -141,7 +143,7 @@ zero bytes.
.. c:function:: void* PyMem_RawMalloc(size_t n)
- Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
+ Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the
allocated memory, or ``NULL`` if the request fails.
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
@@ -152,7 +154,7 @@ zero bytes.
.. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
+ a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
@@ -212,7 +214,7 @@ The :ref:`default memory allocator ` uses the
.. c:function:: void* PyMem_Malloc(size_t n)
- Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
+ Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the
allocated memory, or ``NULL`` if the request fails.
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
@@ -223,7 +225,7 @@ The :ref:`default memory allocator ` uses the
.. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
+ a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
@@ -265,14 +267,14 @@ The following type-oriented macros are provided for convenience. Note that
.. c:function:: TYPE* PyMem_New(TYPE, size_t n)
Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of
- memory. Returns a pointer cast to :c:type:`TYPE*`. The memory will not have
+ memory. Returns a pointer cast to :c:expr:`TYPE*`. The memory will not have
been initialized in any way.
.. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n)
Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n *
- sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE*`. On return,
+ sizeof(TYPE))`` bytes. Returns a pointer cast to :c:expr:`TYPE*`. On return,
*p* will be a pointer to the new memory area, or ``NULL`` in the event of
failure.
@@ -320,7 +322,7 @@ The :ref:`default object allocator ` uses the
.. c:function:: void* PyObject_Malloc(size_t n)
- Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
+ Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the
allocated memory, or ``NULL`` if the request fails.
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
@@ -331,7 +333,7 @@ The :ref:`default object allocator ` uses the
.. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
+ a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
@@ -479,6 +481,25 @@ Customize Memory Allocators
See also :c:member:`PyPreConfig.allocator` and :ref:`Preinitialize Python
with PyPreConfig `.
+ .. warning::
+
+ :c:func:`PyMem_SetAllocator` does have the following contract:
+
+ * It can be called after :c:func:`Py_PreInitialize` and before
+ :c:func:`Py_InitializeFromConfig` to install a custom memory
+ allocator. There are no restrictions over the installed allocator
+ other than the ones imposed by the domain (for instance, the Raw
+ Domain allows the allocator to be called without the GIL held). See
+ :ref:`the section on allocator domains ` for more
+ information.
+
+ * If called after Python has finish initializing (after
+ :c:func:`Py_InitializeFromConfig` has been called) the allocator
+ **must** wrap the existing allocator. Substituting the current
+ allocator for some other arbitrary one is **not supported**.
+
+
+
.. c:function:: void PyMem_SetupDebugHooks(void)
Setup :ref:`debug hooks in the Python memory allocators `
diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst
index 4d94b3f545f327..2aa43318e7a455 100644
--- a/Doc/c-api/memoryview.rst
+++ b/Doc/c-api/memoryview.rst
@@ -3,7 +3,7 @@
.. _memoryview-objects:
.. index::
- object: memoryview
+ pair: object; memoryview
MemoryView objects
------------------
@@ -55,7 +55,7 @@ any other object.
*mview* **must** be a memoryview instance; this macro doesn't check its type,
you must do it yourself or you will risk crashes.
-.. c:function:: Py_buffer *PyMemoryView_GET_BASE(PyObject *mview)
+.. c:function:: PyObject *PyMemoryView_GET_BASE(PyObject *mview)
Return either a pointer to the exporting object that the memoryview is based
on or ``NULL`` if the memoryview has been created by one of the functions
diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst
index 6e7e1e21aa93f2..93ad30cd4f7a8d 100644
--- a/Doc/c-api/method.rst
+++ b/Doc/c-api/method.rst
@@ -5,7 +5,7 @@
Instance Method Objects
-----------------------
-.. index:: object: instancemethod
+.. index:: pair: object; instancemethod
An instance method is a wrapper for a :c:data:`PyCFunction` and the new way
to bind a :c:data:`PyCFunction` to a class object. It replaces the former call
@@ -47,7 +47,7 @@ to bind a :c:data:`PyCFunction` to a class object. It replaces the former call
Method Objects
--------------
-.. index:: object: method
+.. index:: pair: object; method
Methods are bound function objects. Methods are always bound to an instance of
a user-defined class. Unbound methods (methods bound to a class object) are
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 94c8d9f981713f..230b471d473be7 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -5,7 +5,7 @@
Module Objects
--------------
-.. index:: object: module
+.. index:: pair: object; module
.. c:var:: PyTypeObject PyModule_Type
@@ -64,8 +64,8 @@ Module Objects
If *module* is not a module object (or a subtype of a module object),
:exc:`SystemError` is raised and ``NULL`` is returned.
- It is recommended extensions use other :c:func:`PyModule_\*` and
- :c:func:`PyObject_\*` functions rather than directly manipulate a module's
+ It is recommended extensions use other ``PyModule_*`` and
+ ``PyObject_*`` functions rather than directly manipulate a module's
:attr:`~object.__dict__`.
@@ -388,7 +388,7 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and
.. c:function:: PyObject * PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec)
- Create a new module object, given the definition in *module* and the
+ Create a new module object, given the definition in *def* and the
ModuleSpec *spec*. This behaves like :c:func:`PyModule_FromDefAndSpec2`
with *module_api_version* set to :const:`PYTHON_API_VERSION`.
@@ -396,7 +396,7 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and
.. c:function:: PyObject * PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version)
- Create a new module object, given the definition in *module* and the
+ Create a new module object, given the definition in *def* and the
ModuleSpec *spec*, assuming the API version *module_api_version*.
If that version does not match the version of the running interpreter,
a :exc:`RuntimeWarning` is emitted.
diff --git a/Doc/c-api/none.rst b/Doc/c-api/none.rst
index 26d2b7aab201ba..b84a16a28ead56 100644
--- a/Doc/c-api/none.rst
+++ b/Doc/c-api/none.rst
@@ -5,7 +5,7 @@
The ``None`` Object
-------------------
-.. index:: object: None
+.. index:: pair: object; None
Note that the :c:type:`PyTypeObject` for ``None`` is not directly exposed in the
Python/C API. Since ``None`` is a singleton, testing for object identity (using
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
index 11c9c67d36a678..13d3c5af956905 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -64,7 +64,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2)
- .. index:: builtin: divmod
+ .. index:: pair: built-in function; divmod
See the built-in function :func:`divmod`. Returns ``NULL`` on failure. This is
the equivalent of the Python expression ``divmod(o1, o2)``.
@@ -72,7 +72,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3)
- .. index:: builtin: pow
+ .. index:: pair: built-in function; pow
See the built-in function :func:`pow`. Returns ``NULL`` on failure. This is the
equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional.
@@ -94,7 +94,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Absolute(PyObject *o)
- .. index:: builtin: abs
+ .. index:: pair: built-in function; abs
Returns the absolute value of *o*, or ``NULL`` on failure. This is the equivalent
of the Python expression ``abs(o)``.
@@ -192,7 +192,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3)
- .. index:: builtin: pow
+ .. index:: pair: built-in function; pow
See the built-in function :func:`pow`. Returns ``NULL`` on failure. The operation
is done *in-place* when *o1* supports it. This is the equivalent of the Python
@@ -238,7 +238,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Long(PyObject *o)
- .. index:: builtin: int
+ .. index:: pair: built-in function; int
Returns the *o* converted to an integer object on success, or ``NULL`` on
failure. This is the equivalent of the Python expression ``int(o)``.
@@ -246,7 +246,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Float(PyObject *o)
- .. index:: builtin: float
+ .. index:: pair: built-in function; float
Returns the *o* converted to a float object on success, or ``NULL`` on failure.
This is the equivalent of the Python expression ``float(o)``.
@@ -273,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
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index 9dcfd769c64a05..1a0fe332590dc5 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -126,6 +126,14 @@ Object Protocol
A generic implementation for the getter of a ``__dict__`` descriptor. It
creates the dictionary if necessary.
+ This function may also be called to get the :py:attr:`~object.__dict__`
+ of the object *o*. Pass ``NULL`` for *context* when calling it.
+ Since this function may need to allocate memory for the
+ dictionary, it may be more efficient to call :c:func:`PyObject_GetAttr`
+ when accessing an attribute on the object.
+
+ On failure, returns ``NULL`` with an exception set.
+
.. versionadded:: 3.3
@@ -137,6 +145,16 @@ Object Protocol
.. versionadded:: 3.3
+.. c:function:: PyObject** _PyObject_GetDictPtr(PyObject *obj)
+
+ Return a pointer to :py:attr:`~object.__dict__` of the object *obj*.
+ If there is no ``__dict__``, return ``NULL`` without setting an exception.
+
+ This function may need to allocate memory for the
+ dictionary, so it may be more efficient to call :c:func:`PyObject_GetAttr`
+ when accessing an attribute on the object.
+
+
.. c:function:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)
Compare the values of *o1* and *o2* using the operation specified by *opid*,
@@ -161,9 +179,18 @@ Object Protocol
If *o1* and *o2* are the same object, :c:func:`PyObject_RichCompareBool`
will always return ``1`` for :const:`Py_EQ` and ``0`` for :const:`Py_NE`.
+.. c:function:: PyObject* PyObject_Format(PyObject *obj, PyObject *format_spec)
+
+ Format *obj* using *format_spec*. This is equivalent to the Python
+ expression ``format(obj, format_spec)``.
+
+ *format_spec* may be ``NULL``. In this case the call is equivalent
+ to ``format(obj)``.
+ Returns the formatted string on success, ``NULL`` on failure.
+
.. c:function:: PyObject* PyObject_Repr(PyObject *o)
- .. index:: builtin: repr
+ .. index:: pair: built-in function; repr
Compute a string representation of object *o*. Returns the string
representation on success, ``NULL`` on failure. This is the equivalent of the
@@ -175,7 +202,7 @@ Object Protocol
.. c:function:: PyObject* PyObject_ASCII(PyObject *o)
- .. index:: builtin: ascii
+ .. index:: pair: built-in function; ascii
As :c:func:`PyObject_Repr`, compute a string representation of object *o*, but
escape the non-ASCII characters in the string returned by
@@ -200,7 +227,7 @@ Object Protocol
.. c:function:: PyObject* PyObject_Bytes(PyObject *o)
- .. index:: builtin: bytes
+ .. index:: pair: built-in function; bytes
Compute a bytes representation of object *o*. ``NULL`` is returned on
failure and a bytes object on success. This is equivalent to the Python
@@ -251,19 +278,19 @@ Object Protocol
.. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
- .. index:: builtin: hash
+ .. index:: pair: built-in function; hash
Compute and return the hash value of an object *o*. On failure, return ``-1``.
This is the equivalent of the Python expression ``hash(o)``.
.. 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)
- Set a :exc:`TypeError` indicating that ``type(o)`` is not hashable and return ``-1``.
+ Set a :exc:`TypeError` indicating that ``type(o)`` is not :term:`hashable` and return ``-1``.
This function receives special treatment when stored in a ``tp_hash`` slot,
allowing a type to explicitly indicate to the interpreter that it is not
hashable.
@@ -285,14 +312,14 @@ Object Protocol
.. c:function:: PyObject* PyObject_Type(PyObject *o)
- .. index:: builtin: type
+ .. index:: pair: built-in function; type
When *o* is non-``NULL``, returns a type object corresponding to the object type
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 :c:func:`Py_TYPE()` function, which returns a
- pointer of type :c:type:`PyTypeObject*`, except when the incremented reference
+ pointer of type :c:expr:`PyTypeObject*`, except when the incremented reference
count is needed.
@@ -305,7 +332,7 @@ Object Protocol
.. c:function:: Py_ssize_t PyObject_Size(PyObject *o)
Py_ssize_t PyObject_Length(PyObject *o)
- .. index:: builtin: len
+ .. index:: pair: built-in function; len
Return the length of object *o*. If the object *o* provides either the sequence
and mapping protocols, the sequence length is returned. On error, ``-1`` is
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/sequence.rst b/Doc/c-api/sequence.rst
index c78d273f9f149f..402a3e5e09ff56 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -18,7 +18,7 @@ Sequence Protocol
.. c:function:: Py_ssize_t PySequence_Size(PyObject *o)
Py_ssize_t PySequence_Length(PyObject *o)
- .. index:: builtin: len
+ .. index:: pair: built-in function; len
Returns the number of objects in sequence *o* on success, and ``-1`` on
failure. This is equivalent to the Python expression ``len(o)``.
@@ -120,7 +120,7 @@ Sequence Protocol
.. c:function:: PyObject* PySequence_Tuple(PyObject *o)
- .. index:: builtin: tuple
+ .. index:: pair: built-in function; tuple
Return a tuple object with the same contents as the sequence or iterable *o*,
or ``NULL`` on failure. If *o* is a tuple, a new reference will be returned,
diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst
index f0d905bae8ae44..d642a5f1902e2e 100644
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -9,8 +9,8 @@ Set Objects
.. index::
- object: set
- object: frozenset
+ pair: object; set
+ pair: object; frozenset
This section details the public API for :class:`set` and :class:`frozenset`
objects. Any functionality not listed below is best accessed using either
@@ -107,7 +107,7 @@ or :class:`frozenset` or instances of their subtypes.
.. c:function:: Py_ssize_t PySet_Size(PyObject *anyset)
- .. index:: builtin: len
+ .. index:: pair: built-in function; len
Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to
``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index ff5ecf24072c1a..cfd6d20a348990 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -27,7 +27,7 @@ the definition of all other Python objects.
object. In a normal "release" build, it contains only the object's
reference count and a pointer to the corresponding type object.
Nothing is actually declared to be a :c:type:`PyObject`, but every pointer
- to a Python object can be cast to a :c:type:`PyObject*`. Access to the
+ to a Python object can be cast to a :c:expr:`PyObject*`. Access to the
members must be done by using the macros :c:macro:`Py_REFCNT` and
:c:macro:`Py_TYPE`.
@@ -103,7 +103,7 @@ the definition of all other Python objects.
.. versionchanged:: 3.11
:c:func:`Py_TYPE()` is changed to an inline static function.
- The parameter type is no longer :c:type:`const PyObject*`.
+ The parameter type is no longer :c:expr:`const PyObject*`.
.. c:function:: int Py_IS_TYPE(PyObject *o, PyTypeObject *type)
@@ -128,7 +128,7 @@ the definition of all other Python objects.
Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count.
.. versionchanged:: 3.11
- The parameter type is no longer :c:type:`const PyObject*`.
+ The parameter type is no longer :c:expr:`const PyObject*`.
.. versionchanged:: 3.10
:c:func:`Py_REFCNT()` is changed to the inline static function.
@@ -149,7 +149,7 @@ the definition of all other Python objects.
.. versionchanged:: 3.11
:c:func:`Py_SIZE()` is changed to an inline static function.
- The parameter type is no longer :c:type:`const PyVarObject*`.
+ The parameter type is no longer :c:expr:`const PyVarObject*`.
.. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)
@@ -184,7 +184,7 @@ Implementing functions and methods
.. c:type:: PyCFunction
Type of the functions used to implement most Python callables in C.
- Functions of this type take two :c:type:`PyObject*` parameters and return
+ Functions of this type take two :c:expr:`PyObject*` parameters and return
one such value. If the return value is ``NULL``, an exception shall have
been set. If not ``NULL``, the return value is interpreted as the return
value of the function as exposed in Python. The function must return a new
@@ -247,29 +247,30 @@ Implementing functions and methods
Structure used to describe a method of an extension type. This structure has
four fields:
- +------------------+---------------+-------------------------------+
- | Field | C Type | Meaning |
- +==================+===============+===============================+
- | :attr:`ml_name` | const char \* | name of the method |
- +------------------+---------------+-------------------------------+
- | :attr:`ml_meth` | PyCFunction | pointer to the C |
- | | | implementation |
- +------------------+---------------+-------------------------------+
- | :attr:`ml_flags` | int | flag bits indicating how the |
- | | | call should be constructed |
- +------------------+---------------+-------------------------------+
- | :attr:`ml_doc` | const char \* | points to the contents of the |
- | | | docstring |
- +------------------+---------------+-------------------------------+
+ .. c:member:: const char* ml_name
-The :attr:`ml_meth` is a C function pointer. The functions may be of different
-types, but they always return :c:type:`PyObject*`. If the function is not of
+ name of the method
+
+ .. c:member:: PyCFunction ml_meth
+
+ pointer to the C implementation
+
+ .. c:member:: int ml_flags
+
+ flags bits indicating how the call should be constructed
+
+ .. c:member:: const char* ml_doc
+
+ points to the contents of the docstring
+
+The :c:member:`ml_meth` is a C function pointer. The functions may be of different
+types, but they always return :c:expr:`PyObject*`. If the function is not of
the :c:type:`PyCFunction`, the compiler will require a cast in the method table.
Even though :c:type:`PyCFunction` defines the first parameter as
-:c:type:`PyObject*`, it is common that the method implementation uses the
+:c:expr:`PyObject*`, it is common that the method implementation uses the
specific C type of the *self* object.
-The :attr:`ml_flags` field is a bitfield which can include the following flags.
+The :c:member:`ml_flags` field is a bitfield which can include the following flags.
The individual flags indicate either a calling convention or a binding
convention.
@@ -278,7 +279,7 @@ There are these calling conventions:
.. data:: METH_VARARGS
This is the typical calling convention, where the methods have the type
- :c:type:`PyCFunction`. The function expects two :c:type:`PyObject*` values.
+ :c:type:`PyCFunction`. The function expects two :c:expr:`PyObject*` values.
The first one is the *self* object for methods; for module functions, it is
the module object. The second parameter (often called *args*) is a tuple
object representing all arguments. This parameter is typically processed
@@ -299,7 +300,7 @@ There are these calling conventions:
Fast calling convention supporting only positional arguments.
The methods have the type :c:type:`_PyCFunctionFast`.
The first parameter is *self*, the second parameter is a C array
- of :c:type:`PyObject*` values indicating the arguments and the third
+ of :c:expr:`PyObject*` values indicating the arguments and the third
parameter is the number of arguments (the length of the array).
.. versionadded:: 3.7
@@ -315,14 +316,12 @@ There are these calling conventions:
with methods of type :c:type:`_PyCFunctionFastWithKeywords`.
Keyword arguments are passed the same way as in the
:ref:`vectorcall protocol `:
- there is an additional fourth :c:type:`PyObject*` parameter
+ there is an additional fourth :c:expr:`PyObject*` parameter
which is a tuple representing the names of the keyword arguments
(which are guaranteed to be strings)
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
@@ -356,7 +355,7 @@ There are these calling conventions:
Methods with a single object argument can be listed with the :const:`METH_O`
flag, instead of invoking :c:func:`PyArg_ParseTuple` with a ``"O"`` argument.
They have the type :c:type:`PyCFunction`, with the *self* parameter, and a
- :c:type:`PyObject*` parameter representing the single argument.
+ :c:expr:`PyObject*` parameter representing the single argument.
These two constants are not used to indicate the calling convention but the
@@ -367,7 +366,7 @@ method.
.. data:: METH_CLASS
- .. index:: builtin: classmethod
+ .. index:: pair: built-in function; classmethod
The method will be passed the type object as the first parameter rather
than an instance of the type. This is used to create *class methods*,
@@ -377,7 +376,7 @@ method.
.. data:: METH_STATIC
- .. index:: builtin: staticmethod
+ .. index:: pair: built-in function; staticmethod
The method will be passed ``NULL`` as the first parameter rather than an
instance of the type. This is used to create *static methods*, similar to
@@ -522,7 +521,7 @@ Accessing attributes of extension types
| | | getter and setter |
+-------------+------------------+-----------------------------------+
- The ``get`` function takes one :c:type:`PyObject*` parameter (the
+ The ``get`` function takes one :c:expr:`PyObject*` parameter (the
instance) and a function pointer (the associated ``closure``)::
typedef PyObject *(*getter)(PyObject *, void *);
@@ -530,7 +529,7 @@ Accessing attributes of extension types
It should return a new reference on success or ``NULL`` with a set exception
on failure.
- ``set`` functions take two :c:type:`PyObject*` parameters (the instance and
+ ``set`` functions take two :c:expr:`PyObject*` parameters (the instance and
the value to be set) and a function pointer (the associated ``closure``)::
typedef int (*setter)(PyObject *, PyObject *, void *);
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index 5e8d993100f632..517b57b14768bf 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -105,7 +105,7 @@ Operating System Utilities
Return the current signal handler for signal *i*. This is a thin wrapper around
either :c:func:`sigaction` or :c:func:`signal`. Do not call those functions
- directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:type:`void
+ directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:expr:`void
(\*)(int)`.
@@ -114,7 +114,7 @@ Operating System Utilities
Set the signal handler for signal *i* to be *h*; return the old signal handler.
This is a thin wrapper around either :c:func:`sigaction` or :c:func:`signal`. Do
not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef
- alias for :c:type:`void (\*)(int)`.
+ alias for :c:expr:`void (\*)(int)`.
.. c:function:: wchar_t* Py_DecodeLocale(const char* arg, size_t *size)
@@ -348,7 +348,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.
@@ -356,7 +356,7 @@ 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.
@@ -377,7 +377,7 @@ accessible to C code. They all work with the current interpreter thread's
silently abort the operation by raising an error subclassed from
:class:`Exception` (other errors will not be silenced).
- The hook function is of type :c:type:`int (*)(const char *event, PyObject
+ The hook function is of type :c:expr:`int (*)(const char *event, PyObject
*args, void *userData)`, where *args* is guaranteed to be a
:c:type:`PyTupleObject`. The hook function is always called with the GIL
held by the Python interpreter that raised the event.
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index 9b85522600d4e7..0982d29e48dec0 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -5,7 +5,7 @@
Tuple Objects
-------------
-.. index:: object: tuple
+.. index:: pair: object; tuple
.. c:type:: PyTupleObject
@@ -161,7 +161,7 @@ type.
.. c:type:: PyStructSequence_Field
Describes a field of a struct sequence. As a struct sequence is modeled as a
- tuple, all fields are typed as :c:type:`PyObject*`. The index in the
+ tuple, all fields are typed as :c:expr:`PyObject*`. The index in the
:attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which
field of the struct sequence is described.
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index d740e4eb0897e5..52eeef0a008639 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -5,7 +5,7 @@
Type Objects
------------
-.. index:: object: type
+.. index:: pair: object; type
.. c:type:: PyTypeObject
@@ -40,7 +40,7 @@ Type Objects
.. c:function:: unsigned long PyType_GetFlags(PyTypeObject* type)
Return the :c:member:`~PyTypeObject.tp_flags` member of *type*. This function is primarily
- meant for use with `Py_LIMITED_API`; the individual flag bits are
+ meant for use with ``Py_LIMITED_API``; the individual flag bits are
guaranteed to be stable across Python releases, but access to
:c:member:`~PyTypeObject.tp_flags` itself is not part of the limited API.
diff --git a/Doc/c-api/typehints.rst b/Doc/c-api/typehints.rst
index 8b0b9b651e80e6..4c1957a2a1dbca 100644
--- a/Doc/c-api/typehints.rst
+++ b/Doc/c-api/typehints.rst
@@ -15,8 +15,8 @@ two types exist -- :ref:`GenericAlias ` and
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
+ *origin* should be a :c:expr:`PyTypeObject*`, and *args* can be a
+ :c:expr:`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
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index ed434d8fd44fb2..ce327166f3ab0e 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -7,8 +7,8 @@ Type Objects
Perhaps one of the most important structures of the Python object system is the
structure that defines a new type: the :c:type:`PyTypeObject` structure. Type
-objects can be handled using any of the :c:func:`PyObject_\*` or
-:c:func:`PyType_\*` functions, but do not offer much that's interesting to most
+objects can be handled using any of the ``PyObject_*`` or
+``PyType_*`` functions, but do not offer much that's interesting to most
Python applications. These objects are fundamental to how objects behave, so
they are very important to the interpreter itself and to any extension module
that implements new types.
@@ -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 |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
@@ -149,10 +149,16 @@ Quick Reference
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
.. [#slots]
- A slot name in parentheses indicates it is (effectively) deprecated.
- Names in angle brackets should be treated as read-only.
- Names in square brackets are for internal use only.
- "" (as a prefix) means the field is required (must be non-``NULL``).
+
+ **()**: A slot name in parentheses indicates it is (effectively) deprecated.
+
+ **<>**: Names in angle brackets should be initially set to ``NULL`` and
+ treated as read-only.
+
+ **[]**: Names in square brackets are for internal use only.
+
+ **** (as a prefix) means the field is required (must be non-``NULL``).
+
.. [#cols] Columns:
**"O"**: set on :c:type:`PyBaseObject_Type`
@@ -333,7 +339,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 +411,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 +444,13 @@ 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:`PyObject` * | |
+-----------------------------+-----------------------------+----------------------+
| :c:type:`objobjproc` | .. line-block:: | int |
| | | |
@@ -529,7 +536,7 @@ type objects) *must* have the :attr:`ob_size` field.
``PyObject_HEAD_INIT`` macro. For :ref:`statically allocated objects
`, these fields always remain ``NULL``. For :ref:`dynamically
allocated objects `, these two fields are used to link the
- object into a doubly-linked list of *all* live objects on the heap.
+ object into a doubly linked list of *all* live objects on the heap.
This could be used for various debugging purposes; currently the only uses
are the :func:`sys.getobjects` function and to print the objects that are
@@ -727,12 +734,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``.
@@ -802,7 +803,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. c:member:: reprfunc PyTypeObject.tp_repr
- .. index:: builtin: repr
+ .. index:: pair: built-in function; repr
An optional pointer to a function that implements the built-in function
:func:`repr`.
@@ -867,7 +868,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. c:member:: hashfunc PyTypeObject.tp_hash
- .. index:: builtin: hash
+ .. index:: pair: built-in function; hash
An optional pointer to a function that implements the built-in function
:func:`hash`.
@@ -1219,6 +1220,17 @@ and :c:type:`PyType_Type` effectively act as defaults.)
**Inheritance:**
This flag is not inherited.
+ However, subclasses will not be instantiable unless they provide a
+ non-NULL :c:member:`~PyTypeObject.tp_new` (which is only possible
+ via the C API).
+
+ .. note::
+
+ To disallow instantiating a class directly but allow instantiating
+ its subclasses (e.g. for an :term:`abstract base class`),
+ do not use this flag.
+ Instead, make :c:member:`~PyTypeObject.tp_new` only succeed for
+ subclasses.
.. versionadded:: 3.10
@@ -1490,8 +1502,8 @@ and :c:type:`PyType_Type` effectively act as defaults.)
If the instances of this type are weakly referenceable, this field is greater
than zero and contains the offset in the instance structure of the weak
reference list head (ignoring the GC header, if present); this offset is used by
- :c:func:`PyObject_ClearWeakRefs` and the :c:func:`PyWeakref_\*` functions. The
- instance structure needs to include a field of type :c:type:`PyObject*` which is
+ :c:func:`PyObject_ClearWeakRefs` and the ``PyWeakref_*`` functions. The
+ instance structure needs to include a field of type :c:expr:`PyObject*` which is
initialized to ``NULL``.
Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for
@@ -1715,18 +1727,11 @@ and :c:type:`PyType_Type` effectively act as defaults.)
:c:member:`~PyTypeObject.tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is
at the very end of the structure.
- The real dictionary offset in an instance can be computed from a negative
- :c:member:`~PyTypeObject.tp_dictoffset` as follows::
-
- dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset
- if dictoffset is not aligned on sizeof(void*):
- round up to sizeof(void*)
-
- where :c:member:`~PyTypeObject.tp_basicsize`, :c:member:`~PyTypeObject.tp_itemsize` and :c:member:`~PyTypeObject.tp_dictoffset` are
- taken from the type object, and :attr:`ob_size` is taken from the instance. The
- absolute value is taken because ints use the sign of :attr:`ob_size` to
- store the sign of the number. (There's never a need to do this calculation
- yourself; it is done for you by :c:func:`_PyObject_GetDictPtr`.)
+ The :c:member:`~PyTypeObject.tp_dictoffset` should be regarded as write-only.
+ To get the pointer to the dictionary call :c:func:`PyObject_GenericGetDict`.
+ Calling :c:func:`PyObject_GenericGetDict` may need to allocate memory for the
+ dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr`
+ when accessing an attribute on the object.
**Inheritance:**
@@ -1905,8 +1910,19 @@ and :c:type:`PyType_Type` effectively act as defaults.)
Tuple of base types.
- This is set for types created by a class statement. It should be ``NULL`` for
- statically defined types.
+ This field should be set to ``NULL`` and treated as read-only.
+ Python will fill it in when the type is :c:func:`initialized `.
+
+ For dynamically created classes, the ``Py_tp_bases``
+ :c:type:`slot ` can be used instead of the *bases* argument
+ of :c:func:`PyType_FromSpecWithBases`.
+ The argument form is preferred.
+
+ .. warning::
+
+ Multiple inheritance does not work well for statically defined types.
+ If you set ``tp_bases`` to a tuple, Python will not raise an error,
+ but some slots will only be inherited from the first base.
**Inheritance:**
@@ -1918,6 +1934,8 @@ and :c:type:`PyType_Type` effectively act as defaults.)
Tuple containing the expanded set of base types, starting with the type itself
and ending with :class:`object`, in Method Resolution Order.
+ This field should be set to ``NULL`` and treated as read-only.
+ Python will fill it in when the type is :c:func:`initialized `.
**Inheritance:**
@@ -1997,9 +2015,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
PyErr_Restore(error_type, error_value, error_traceback);
}
- 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
@@ -2017,6 +2032,12 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. versionadded:: 3.4
+ .. versionchanged:: 3.8
+
+ Before version 3.8 it was necessary to set the
+ :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be
+ used. This is no longer required.
+
.. seealso:: "Safe object finalization" (:pep:`442`)
@@ -2054,9 +2075,9 @@ This results in types that are limited relative to types defined in Python:
:ref:`sub-interpreters `, so they should not
include any subinterpreter-specific state.
-Also, since :c:type:`PyTypeObject` is not part of the :ref:`stable ABI `,
-any extension modules using static types must be compiled for a specific
-Python minor version.
+Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API
+` as an opaque struct, any extension modules using static types must be
+compiled for a specific Python minor version.
.. _heap-types:
@@ -2331,13 +2352,13 @@ Buffer Object Structures
steps:
(1) Check if the request can be met. If not, raise :c:data:`PyExc_BufferError`,
- set :c:data:`view->obj` to ``NULL`` and return ``-1``.
+ set :c:expr:`view->obj` to ``NULL`` and return ``-1``.
(2) Fill in the requested fields.
(3) Increment an internal counter for the number of exports.
- (4) Set :c:data:`view->obj` to *exporter* and increment :c:data:`view->obj`.
+ (4) Set :c:expr:`view->obj` to *exporter* and increment :c:expr:`view->obj`.
(5) Return ``0``.
@@ -2345,10 +2366,10 @@ Buffer Object Structures
schemes can be used:
* Re-export: Each member of the tree acts as the exporting object and
- sets :c:data:`view->obj` to a new reference to itself.
+ sets :c:expr:`view->obj` to a new reference to itself.
* Redirect: The buffer request is redirected to the root object of the
- tree. Here, :c:data:`view->obj` will be a new reference to the root
+ tree. Here, :c:expr:`view->obj` will be a new reference to the root
object.
The individual fields of *view* are described in section
@@ -2390,7 +2411,7 @@ Buffer Object Structures
*view* argument.
- This function MUST NOT decrement :c:data:`view->obj`, since that is
+ This function MUST NOT decrement :c:expr:`view->obj`, since that is
done automatically in :c:func:`PyBuffer_Release` (this scheme is
useful for breaking reference cycles).
@@ -2529,11 +2550,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 *)
@@ -2569,7 +2590,7 @@ Slot Type typedefs
.. c:type:: PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t)
-.. c:type:: int (*ssizeobjargproc)(PyObject *, Py_ssize_t)
+.. c:type:: int (*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *)
.. c:type:: int (*objobjproc)(PyObject *, PyObject *)
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index d139112578ca99..12f95a2e8a39d0 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -17,8 +17,8 @@ of Unicode characters while staying memory efficient. There are special cases
for strings where all code points are below 128, 256, or 65536; otherwise, code
points must be below 1114112 (which is the full Unicode range).
-:c:type:`Py_UNICODE*` and UTF-8 representations are created on demand and cached
-in the Unicode object. The :c:type:`Py_UNICODE*` representation is deprecated
+:c:expr:`Py_UNICODE*` and UTF-8 representations are created on demand and cached
+in the Unicode object. The :c:expr:`Py_UNICODE*` representation is deprecated
and inefficient.
Due to the transition between the old APIs and the new APIs, Unicode objects
@@ -30,7 +30,7 @@ can internally be in two states depending on how they were created:
* "legacy" Unicode objects have been created through one of the deprecated
APIs (typically :c:func:`PyUnicode_FromUnicode`) and only bear the
- :c:type:`Py_UNICODE*` representation; you will have to call
+ :c:expr:`Py_UNICODE*` representation; you will have to call
:c:func:`PyUnicode_READY` on them before calling any other API.
.. note::
@@ -58,7 +58,7 @@ Python:
.. c:type:: Py_UNICODE
- This is a typedef of :c:type:`wchar_t`, which is a 16-bit type or 32-bit type
+ This is a typedef of :c:expr:`wchar_t`, which is a 16-bit type or 32-bit type
depending on the platform.
.. versionchanged:: 3.3
@@ -149,7 +149,7 @@ access to internal read-only data of Unicode objects:
``PyUnicode_WCHAR_KIND`` is deprecated.
-.. c:function:: unsigned int PyUnicode_KIND(PyObject *o)
+.. c:function:: 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
@@ -168,7 +168,7 @@ access to internal read-only data of Unicode objects:
.. versionadded:: 3.3
-.. c:function:: void PyUnicode_WRITE(unsigned int kind, void *data, \
+.. c:function:: void PyUnicode_WRITE(int kind, void *data, \
Py_ssize_t index, Py_UCS4 value)
Write into a canonical representation *data* (as obtained with
@@ -181,7 +181,7 @@ access to internal read-only data of Unicode objects:
.. versionadded:: 3.3
-.. c:function:: Py_UCS4 PyUnicode_READ(unsigned int kind, void *data, \
+.. c:function:: Py_UCS4 PyUnicode_READ(int kind, void *data, \
Py_ssize_t index)
Read a code point from a canonical representation *data* (as obtained with
@@ -236,7 +236,7 @@ access to internal read-only data of Unicode objects:
returned buffer is always terminated with an extra null code point. It
may also contain embedded null code points, which would cause the string
to be truncated when used in most C functions. The ``AS_DATA`` form
- casts the pointer to :c:type:`const char *`. The *o* argument has to be
+ casts the pointer to :c:expr:`const char *`. The *o* argument has to be
a Unicode object (not checked).
.. versionchanged:: 3.3
@@ -497,11 +497,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]_ |
@@ -572,6 +572,15 @@ APIs:
arguments.
+.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj)
+
+ Copy an instance of a Unicode subtype to a new true Unicode object if
+ necessary. If *obj* is already a true Unicode object (not a subtype),
+ return the reference with incremented refcount.
+
+ Objects other than Unicode or its subtypes will cause a :exc:`TypeError`.
+
+
.. c:function:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, \
const char *encoding, const char *errors)
@@ -714,7 +723,7 @@ Extension modules can continue using them, as they will not be removed in Python
Return a read-only pointer to the Unicode object's internal
:c:type:`Py_UNICODE` buffer, or ``NULL`` on error. This will create the
- :c:type:`Py_UNICODE*` representation of the object if it is not yet
+ :c:expr:`Py_UNICODE*` representation of the object if it is not yet
available. The buffer is always terminated with an extra null code point.
Note that the resulting :c:type:`Py_UNICODE` string may also contain
embedded null code points, which would cause the string to be truncated when
@@ -730,7 +739,7 @@ Extension modules can continue using them, as they will not be removed in Python
Like :c:func:`PyUnicode_AsUnicode`, but also saves the :c:func:`Py_UNICODE`
array length (excluding the extra null terminator) in *size*.
- Note that the resulting :c:type:`Py_UNICODE*` string
+ Note that the resulting :c:expr:`Py_UNICODE*` string
may contain embedded null code points, which would cause the string to be
truncated when used in most C functions.
@@ -752,15 +761,6 @@ Extension modules can continue using them, as they will not be removed in Python
:c:func:`PyUnicode_GET_LENGTH`.
-.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj)
-
- Copy an instance of a Unicode subtype to a new true Unicode object if
- necessary. If *obj* is already a true Unicode object (not a subtype),
- return the reference with incremented refcount.
-
- Objects other than Unicode or its subtypes will cause a :exc:`TypeError`.
-
-
Locale Encoding
"""""""""""""""
@@ -849,7 +849,7 @@ argument parsing, the ``"O&"`` converter should be used, passing
ParseTuple converter: encode :class:`str` objects -- obtained directly or
through the :class:`os.PathLike` interface -- to :class:`bytes` using
:c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is.
- *result* must be a :c:type:`PyBytesObject*` which must be released when it is
+ *result* must be a :c:expr:`PyBytesObject*` which must be released when it is
no longer used.
.. versionadded:: 3.1
@@ -866,7 +866,7 @@ conversion function:
ParseTuple converter: decode :class:`bytes` objects -- obtained either
directly or indirectly through the :class:`os.PathLike` interface -- to
:class:`str` using :c:func:`PyUnicode_DecodeFSDefaultAndSize`; :class:`str`
- objects are output as-is. *result* must be a :c:type:`PyUnicodeObject*` which
+ objects are output as-is. *result* must be a :c:expr:`PyUnicodeObject*` which
must be released when it is no longer used.
.. versionadded:: 3.2
@@ -935,11 +935,11 @@ conversion function:
wchar_t Support
"""""""""""""""
-:c:type:`wchar_t` support for platforms which support it:
+:c:expr:`wchar_t` support for platforms which support it:
.. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)
- Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*.
+ Create a Unicode object from the :c:expr:`wchar_t` buffer *w* of the given *size*.
Passing ``-1`` as the *size* indicates that the function must itself compute the length,
using wcslen.
Return ``NULL`` on failure.
@@ -947,13 +947,13 @@ wchar_t Support
.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size)
- Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most
- *size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing
- null termination character). Return the number of :c:type:`wchar_t` characters
- copied or ``-1`` in case of an error. Note that the resulting :c:type:`wchar_t*`
+ Copy the Unicode object contents into the :c:expr:`wchar_t` buffer *w*. At most
+ *size* :c:expr:`wchar_t` characters are copied (excluding a possibly trailing
+ null termination character). Return the number of :c:expr:`wchar_t` characters
+ copied or ``-1`` in case of an error. Note that the resulting :c:expr:`wchar_t*`
string may or may not be null-terminated. It is the responsibility of the caller
- to make sure that the :c:type:`wchar_t*` string is null-terminated in case this is
- required by the application. Also, note that the :c:type:`wchar_t*` string
+ to make sure that the :c:expr:`wchar_t*` string is null-terminated in case this is
+ required by the application. Also, note that the :c:expr:`wchar_t*` string
might contain null characters, which would cause the string to be truncated
when used with most C functions.
@@ -963,9 +963,9 @@ wchar_t Support
Convert the Unicode object to a wide character string. The output string
always ends with a null character. If *size* is not ``NULL``, write the number
of wide characters (excluding the trailing null termination character) into
- *\*size*. Note that the resulting :c:type:`wchar_t` string might contain
+ *\*size*. Note that the resulting :c:expr:`wchar_t` string might contain
null characters, which would cause the string to be truncated when used with
- most C functions. If *size* is ``NULL`` and the :c:type:`wchar_t*` string
+ most C functions. If *size* is ``NULL`` and the :c:expr:`wchar_t*` string
contains null characters a :exc:`ValueError` is raised.
Returns a buffer allocated by :c:func:`PyMem_Alloc` (use
@@ -976,7 +976,7 @@ wchar_t Support
.. versionadded:: 3.2
.. versionchanged:: 3.7
- Raises a :exc:`ValueError` if *size* is ``NULL`` and the :c:type:`wchar_t*`
+ Raises a :exc:`ValueError` if *size* is ``NULL`` and the :c:expr:`wchar_t*`
string contains null characters.
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 7bd47bb9c660a6..bfb14ac912fcac 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -16,11 +16,11 @@ parameter. The available start symbols are :const:`Py_eval_input`,
:const:`Py_file_input`, and :const:`Py_single_input`. These are described
following the functions which accept them as parameters.
-Note also that several of these functions take :c:type:`FILE*` parameters. One
-particular issue which needs to be handled carefully is that the :c:type:`FILE`
+Note also that several of these functions take :c:expr:`FILE*` parameters. One
+particular issue which needs to be handled carefully is that the :c:expr:`FILE`
structure for different C libraries can be different and incompatible. Under
Windows (at least), it is possible for dynamically linked extensions to actually
-use different libraries, so care should be taken that :c:type:`FILE*` parameters
+use different libraries, so care should be taken that :c:expr:`FILE*` parameters
are only passed to these functions if it is certain that they were created by
the same library that the Python runtime is using.
@@ -82,7 +82,7 @@ the same library that the Python runtime is using.
.. c:function:: int PyRun_SimpleString(const char *command)
This is a simplified interface to :c:func:`PyRun_SimpleStringFlags` below,
- leaving the :c:type:`PyCompilerFlags`\* argument set to ``NULL``.
+ leaving the :c:struct:`PyCompilerFlags`\* argument set to ``NULL``.
.. c:function:: int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
@@ -338,7 +338,7 @@ the same library that the Python runtime is using.
interpreter loop.
-.. c:type:: struct PyCompilerFlags
+.. c:struct:: PyCompilerFlags
This is the structure used to hold compiler flags. In cases where code is only
being compiled, it is passed as ``int flags``, and in cases where code is being
diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst
index 7b32e17a239729..f27ec4411b4a26 100644
--- a/Doc/c-api/weakref.rst
+++ b/Doc/c-api/weakref.rst
@@ -35,7 +35,7 @@ as much as it can.
callable object that receives notification when *ob* is garbage collected; it
should accept a single parameter, which will be the weak reference object
itself. *callback* may also be ``None`` or ``NULL``. If *ob* is not a
- weakly-referencable object, or if *callback* is not callable, ``None``, or
+ weakly referencable object, or if *callback* is not callable, ``None``, or
``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
@@ -47,7 +47,7 @@ as much as it can.
be a callable object that receives notification when *ob* is garbage
collected; it should accept a single parameter, which will be the weak
reference object itself. *callback* may also be ``None`` or ``NULL``. If *ob*
- is not a weakly-referencable object, or if *callback* is not callable,
+ is not a weakly referencable object, or if *callback* is not callable,
``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
@@ -67,3 +67,13 @@ as much as it can.
.. c:function:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref)
Similar to :c:func:`PyWeakref_GetObject`, but does no error checking.
+
+
+.. c:function:: void PyObject_ClearWeakRefs(PyObject *object)
+
+ This function is called by the :c:member:`~PyTypeObject.tp_dealloc` handler
+ to clear weak references.
+
+ This iterates through the weak references for *object* and calls callbacks
+ for those references which have one. It returns when all callbacks have
+ been attempted.
diff --git a/Doc/conf.py b/Doc/conf.py
index e539da539e6551..3bd828f8ce9ed7 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -13,9 +13,25 @@
# General configuration
# ---------------------
-extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest',
- 'pyspecific', 'c_annotations', 'escape4chm',
- 'asdl_highlight', 'peg_highlight', 'glossary_search']
+extensions = [
+ 'asdl_highlight',
+ 'c_annotations',
+ 'escape4chm',
+ 'glossary_search',
+ 'peg_highlight',
+ 'pyspecific',
+ 'sphinx.ext.coverage',
+ 'sphinx.ext.doctest',
+]
+
+# Skip if downstream redistributors haven't installed it
+try:
+ import sphinxext.opengraph
+except ImportError:
+ pass
+else:
+ extensions.append('sphinxext.opengraph')
+
doctest_global_setup = '''
try:
@@ -45,14 +61,23 @@
highlight_language = 'python3'
# Minimum version of sphinx required
-needs_sphinx = '1.8'
+needs_sphinx = '3.2'
+# Ignore any .rst files in the includes/ directory;
+# they're embedded in pages but not rendered individually.
# Ignore any .rst files in the venv/ directory.
-exclude_patterns = ['venv/*', 'README.rst']
+exclude_patterns = ['includes/*.rst', 'venv/*', 'README.rst']
venvdir = os.getenv('VENVDIR')
if venvdir is not None:
exclude_patterns.append(venvdir + '/*')
+nitpick_ignore = [
+ # Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot
+ # be resolved, as the method is currently undocumented. For context, see
+ # https://github.com/python/cpython/pull/103289.
+ ('py:meth', '_SubParsersAction.add_parser'),
+]
+
# Disable Docutils smartquotes for several translations
smartquotes_excludes = {
'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], 'builders': ['man', 'text'],
@@ -61,6 +86,11 @@
# Avoid a warning with Sphinx >= 2.0
master_doc = 'contents'
+# Allow translation of index directives
+gettext_additional_targets = [
+ 'index',
+]
+
# Options for HTML output
# -----------------------
@@ -74,9 +104,25 @@
'root_include_title': False # We use the version switcher instead.
}
+# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207
+# https://github.com/python/cpython/issues/91207
+if any('htmlhelp' in arg for arg in sys.argv):
+ html_style = 'pydoctheme.css'
+ print("\nWARNING: Windows CHM Help is no longer supported.")
+ print("It may be removed in the future\n")
+
# Short title used e.g. for HTML tags.
html_short_title = '%s Documentation' % release
+# Deployment preview information
+# (See .readthedocs.yml and https://docs.readthedocs.io/en/stable/reference/environment-variables.html)
+repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL")
+html_context = {
+ "is_deployment_preview": os.getenv("READTHEDOCS_VERSION_TYPE") == "external",
+ "repository_url": repository_url.removesuffix(".git") if repository_url else None,
+ "pr_id": os.getenv("READTHEDOCS_VERSION")
+}
+
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
@@ -102,7 +148,7 @@
html_use_opensearch = 'https://docs.python.org/' + version
# Additional static files.
-html_static_path = ['tools/static']
+html_static_path = ['_static', 'tools/static']
# Output file base name for HTML help builder.
htmlhelp_basename = 'python' + release.replace('.', '')
@@ -217,8 +263,49 @@
# Options for the link checker
# ----------------------------
-# Ignore certain URLs.
-linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+']
+linkcheck_allowed_redirects = {
+ # bpo-NNNN -> BPO -> GH Issues
+ r'https://bugs.python.org/issue\?@action=redirect&bpo=\d+': r'https://github.com/python/cpython/issues/\d+',
+ # GH-NNNN used to refer to pull requests
+ r'https://github.com/python/cpython/issues/\d+': r'https://github.com/python/cpython/pull/\d+',
+ # :source:`something` linking files in the repository
+ r'https://github.com/python/cpython/tree/.*': 'https://github.com/python/cpython/blob/.*',
+ # Intentional HTTP use at Misc/NEWS.d/3.5.0a1.rst
+ r'http://www.python.org/$': 'https://www.python.org/$',
+ # Used in license page, keep as is
+ r'https://www.zope.org/': r'https://www.zope.dev/',
+ # Microsoft's redirects to learn.microsoft.com
+ r'https://msdn.microsoft.com/.*': 'https://learn.microsoft.com/.*',
+ r'https://docs.microsoft.com/.*': 'https://learn.microsoft.com/.*',
+ r'https://go.microsoft.com/fwlink/\?LinkID=\d+': 'https://learn.microsoft.com/.*',
+ # Language redirects
+ r'https://toml.io': 'https://toml.io/en/',
+ r'https://www.redhat.com': 'https://www.redhat.com/en',
+ # Other redirects
+ r'https://www.boost.org/libs/.+': r'https://www.boost.org/doc/libs/\d_\d+_\d/.+',
+ r'https://support.microsoft.com/en-us/help/\d+': 'https://support.microsoft.com/en-us/topic/.+',
+ r'https://perf.wiki.kernel.org$': 'https://perf.wiki.kernel.org/index.php/Main_Page',
+ r'https://www.sqlite.org': 'https://www.sqlite.org/index.html',
+ r'https://mitpress.mit.edu/sicp$': 'https://mitpress.mit.edu/9780262510875/structure-and-interpretation-of-computer-programs/',
+ r'https://www.python.org/psf/': 'https://www.python.org/psf-landing/',
+}
+
+linkcheck_anchors_ignore = [
+ # ignore anchors that start with a '/', e.g. Wikipedia media files:
+ # https://en.wikipedia.org/wiki/Walrus#/media/File:Pacific_Walrus_-_Bull_(8247646168).jpg
+ r'\/.*',
+]
+
+linkcheck_ignore = [
+ # The crawler gets "Anchor not found"
+ r'https://developer.apple.com/documentation/.+?#.*',
+ r'https://devguide.python.org.+?/#.*',
+ r'https://github.com.+?#.*',
+ # Robot crawlers not allowed: "403 Client Error: Forbidden"
+ r'https://support.enthought.com/hc/.*',
+ # SSLError CertificateError, even though it is valid
+ r'https://unix.org/version2/whatsnew/lp64_wp.html',
+]
# Options for extensions
@@ -228,14 +315,12 @@
refcount_file = 'data/refcounts.dat'
stable_abi_file = 'data/stable_abi.dat'
-# Sphinx 2 and Sphinx 3 compatibility
-# -----------------------------------
-
-# bpo-40204: Allow Sphinx 2 syntax in the C domain
-c_allow_pre_v3 = True
-
-# 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
+# sphinxext-opengraph config
+ogp_site_url = 'https://docs.python.org/3/'
+ogp_site_name = 'Python documentation'
+ogp_image = '_static/og-image.png'
+ogp_custom_meta_tags = [
+ '',
+ '',
+ '',
+]
diff --git a/Doc/constraints.txt b/Doc/constraints.txt
new file mode 100644
index 00000000000000..66c748eb092d83
--- /dev/null
+++ b/Doc/constraints.txt
@@ -0,0 +1,29 @@
+# We have upper bounds on our transitive dependencies here
+# To avoid new releases unexpectedly breaking our build.
+# This file can be updated on an ad-hoc basis,
+# though it will probably have to be updated
+# whenever Doc/requirements.txt is updated.
+
+# Direct dependencies of Sphinx
+babel<3
+colorama<0.5
+imagesize<1.5
+Jinja2<3.2
+packaging<24
+# Pygments==2.15.0 breaks CI
+Pygments<2.16,!=2.15.0
+requests<3
+snowballstemmer<3
+sphinxcontrib-applehelp<1.1
+sphinxcontrib-devhelp<1.1
+sphinxcontrib-htmlhelp<2.1
+sphinxcontrib-jsmath<1.1
+sphinxcontrib-qthelp<1.1
+sphinxcontrib-serializinghtml<1.2
+
+# Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above)
+MarkupSafe<2.2
+
+# Direct dependencies of sphinx-lint
+polib<1.3
+regex<2024
diff --git a/Doc/copyright.rst b/Doc/copyright.rst
index e64a49328b4723..9b71683155eebe 100644
--- a/Doc/copyright.rst
+++ b/Doc/copyright.rst
@@ -4,7 +4,7 @@ Copyright
Python and this documentation is:
-Copyright © 2001-2022 Python Software Foundation. All rights reserved.
+Copyright © 2001-2023 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
diff --git a/Doc/data/python3.11.abi b/Doc/data/python3.11.abi
new file mode 100644
index 00000000000000..14ffe9cab2c33d
--- /dev/null
+++ b/Doc/data/python3.11.abi
@@ -0,0 +1,16643 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 1694cad6f43ba7..cbd22a3e23ece5 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -1010,10 +1010,10 @@ PyImport_Import:PyObject*::+1:
PyImport_Import:PyObject*:name:0:
PyImport_ImportFrozenModule:int:::
-PyImport_ImportFrozenModule:const char*:::
+PyImport_ImportFrozenModule:const char*:name::
PyImport_ImportFrozenModuleObject:int:::
-PyImport_ImportFrozenModuleObject:PyObject*::+1:
+PyImport_ImportFrozenModuleObject:PyObject*:name:+1:
PyImport_ImportModule:PyObject*::+1:
PyImport_ImportModule:const char*:name::
diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst
index 136cf4e77b1543..8e70c24e70266d 100644
--- a/Doc/distributing/index.rst
+++ b/Doc/distributing/index.rst
@@ -130,14 +130,10 @@ involved in creating and publishing a project:
* `Uploading the project to the Python Package Index`_
* `The .pypirc file`_
-.. _Project structure: \
- https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects
-.. _Building and packaging the project: \
- 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/
+.. _Project structure: https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects
+.. _Building and packaging the project: 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/
How do I...?
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index 18a4aac4f70895..56bed7d63f1e90 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
@@ -1021,7 +1021,7 @@ directories.
Files in *src* that begin with :file:`.nfs` are skipped (more information on
these files is available in answer D2 of the `NFS FAQ page
- `_).
+ `_).
.. versionchanged:: 3.3.1
NFS files are ignored.
@@ -1198,7 +1198,7 @@ other utility module.
it contains certain values: see :func:`check_environ`. Raise :exc:`ValueError`
for any variables not found in either *local_vars* or ``os.environ``.
- Note that this is not a fully-fledged string interpolation function. A valid
+ Note that this is not a full-fledged string interpolation function. A valid
``$variable`` can consist only of upper and lower case letters, numbers and an
underscore. No { } or ( ) style quoting is available.
diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst
index e492b7f6057596..49e4b6e4b984de 100644
--- a/Doc/distutils/examples.rst
+++ b/Doc/distutils/examples.rst
@@ -337,4 +337,4 @@ loads its values::
.. % \section{Putting it all together}
-.. _docutils: http://docutils.sourceforge.net
+.. _docutils: https://docutils.sourceforge.io
diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst
index 4386a60b664bfb..8635c911622b2f 100644
--- a/Doc/distutils/setupscript.rst
+++ b/Doc/distutils/setupscript.rst
@@ -642,7 +642,7 @@ Notes:
'long string'
Multiple lines of plain text in reStructuredText format (see
- http://docutils.sourceforge.net/).
+ https://docutils.sourceforge.io/).
'list of strings'
See below.
diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst
index 69dffbd56abf11..53817074ab1ee5 100644
--- a/Doc/extending/building.rst
+++ b/Doc/extending/building.rst
@@ -17,7 +17,7 @@ The initialization function has the signature:
.. c:function:: PyObject* PyInit_modulename(void)
-It returns either a fully-initialized module, or a :c:type:`PyModuleDef`
+It returns either a fully initialized module, or a :c:type:`PyModuleDef`
instance. See :ref:`initializing-modules` for details.
.. highlight:: python
diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst
index 5f5abdf9c15067..e64db373344038 100644
--- a/Doc/extending/embedding.rst
+++ b/Doc/extending/embedding.rst
@@ -298,16 +298,16 @@ be directly useful to you:
.. code-block:: shell-session
- $ /opt/bin/python3.4-config --cflags
- -I/opt/include/python3.4m -I/opt/include/python3.4m -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
+ $ /opt/bin/python3.11-config --cflags
+ -I/opt/include/python3.11 -I/opt/include/python3.11 -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall
-* ``pythonX.Y-config --ldflags`` will give you the recommended flags when
- linking:
+* ``pythonX.Y-config --ldflags --embed`` will give you the recommended flags
+ when linking:
.. code-block:: shell-session
- $ /opt/bin/python3.4-config --ldflags
- -L/opt/lib/python3.4/config-3.4m -lpthread -ldl -lutil -lm -lpython3.4m -Xlinker -export-dynamic
+ $ /opt/bin/python3.11-config --ldflags --embed
+ -L/opt/lib/python3.11/config-3.11-x86_64-linux-gnu -L/opt/lib -lpython3.11 -lpthread -ldl -lutil -lm
.. note::
To avoid confusion between several Python installations (and especially
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index 2e3362b834e6fb..d9bf4fd6c7ae0e 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -157,16 +157,16 @@ since you should be able to tell from the return value.
When a function *f* that calls another function *g* detects that the latter
fails, *f* should itself return an error value (usually ``NULL`` or ``-1``). It
-should *not* call one of the :c:func:`PyErr_\*` functions --- one has already
+should *not* call one of the ``PyErr_*`` functions --- one has already
been called by *g*. *f*'s caller is then supposed to also return an error
-indication to *its* caller, again *without* calling :c:func:`PyErr_\*`, and so on
+indication to *its* caller, again *without* calling ``PyErr_*``, and so on
--- the most detailed cause of the error was already reported by the function
that first detected it. Once the error reaches the Python interpreter's main
loop, this aborts the currently executing Python code and tries to find an
exception handler specified by the Python programmer.
(There are situations where a module can actually give a more detailed error
-message by calling another :c:func:`PyErr_\*` function, and in such cases it is
+message by calling another ``PyErr_*`` function, and in such cases it is
fine to do so. As a general rule, however, this is not necessary, and can cause
information about the cause of the error to be lost: most operations can fail
for a variety of reasons.)
@@ -298,7 +298,7 @@ In this case, it will return an integer object. (Yes, even integers are objects
on the heap in Python!)
If you have a C function that returns no useful argument (a function returning
-:c:type:`void`), the corresponding Python function must return ``None``. You
+:c:expr:`void`), the corresponding Python function must return ``None``. You
need this idiom to do so (which is implemented by the :c:macro:`Py_RETURN_NONE`
macro)::
@@ -1171,7 +1171,7 @@ other extension modules must be exported in a different way.
Python provides a special mechanism to pass C-level information (pointers) from
one extension module to another one: Capsules. A Capsule is a Python data type
-which stores a pointer (:c:type:`void \*`). Capsules can only be created and
+which stores a pointer (:c:expr:`void \*`). Capsules can only be created and
accessed via their C API, but they can be passed around like any other Python
object. In particular, they can be assigned to a name in an extension module's
namespace. Other extension modules can then import this module, retrieve the
@@ -1185,7 +1185,7 @@ different ways between the module providing the code and the client modules.
Whichever method you choose, it's important to name your Capsules properly.
The function :c:func:`PyCapsule_New` takes a name parameter
-(:c:type:`const char \*`); you're permitted to pass in a ``NULL`` name, but
+(:c:expr:`const char \*`); you're permitted to pass in a ``NULL`` name, but
we strongly encourage you to specify a name. Properly named Capsules provide
a degree of runtime type-safety; there is no feasible way to tell one unnamed
Capsule from another.
@@ -1203,7 +1203,7 @@ of certainty that the Capsule they load contains the correct C API.
The following example demonstrates an approach that puts most of the burden on
the writer of the exporting module, which is appropriate for commonly used
library modules. It stores all C API pointers (just one in the example!) in an
-array of :c:type:`void` pointers which becomes the value of a Capsule. The header
+array of :c:expr:`void` pointers which becomes the value of a Capsule. The header
file corresponding to the module provides a macro that takes care of importing
the module and retrieving its C API pointers; client modules only have to call
this macro before accessing the C API.
diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst
index 0994e3e8627dfa..01b4df6d44acff 100644
--- a/Doc/extending/index.rst
+++ b/Doc/extending/index.rst
@@ -27,8 +27,8 @@ Recommended third party tools
This guide only covers the basic tools for creating extensions provided
as part of this version of CPython. Third party tools like
-`Cython `_, `cffi `_,
-`SWIG `_ and `Numba `_
+`Cython `_, `cffi `_,
+`SWIG `_ and `Numba `_
offer both simpler and more sophisticated approaches to creating C and C++
extensions for Python.
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index f75bee9e6f2a2b..e60db11b5f10f4 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -149,7 +149,7 @@ done. This can be done using the :c:func:`PyErr_Fetch` and
.. index::
single: string; object representation
- builtin: repr
+ pair: built-in function; repr
Object Presentation
-------------------
@@ -175,7 +175,7 @@ example::
}
If no :c:member:`~PyTypeObject.tp_repr` handler is specified, the interpreter will supply a
-representation that uses the type's :c:member:`~PyTypeObject.tp_name` and a uniquely-identifying
+representation that uses the type's :c:member:`~PyTypeObject.tp_name` and a uniquely identifying
value for the object.
The :c:member:`~PyTypeObject.tp_str` handler is to :func:`str` what the :c:member:`~PyTypeObject.tp_repr` handler
@@ -207,8 +207,8 @@ a special case, for which the new value passed to the handler is ``NULL``.
Python supports two pairs of attribute handlers; a type that supports attributes
only needs to implement the functions for one pair. The difference is that one
-pair takes the name of the attribute as a :c:type:`char\*`, while the other
-accepts a :c:type:`PyObject\*`. Each type can use whichever pair makes more
+pair takes the name of the attribute as a :c:expr:`char\*`, while the other
+accepts a :c:expr:`PyObject*`. Each type can use whichever pair makes more
sense for the implementation's convenience. ::
getattrfunc tp_getattr; /* char * version */
@@ -219,7 +219,7 @@ sense for the implementation's convenience. ::
If accessing attributes of an object is always a simple operation (this will be
explained shortly), there are generic implementations which can be used to
-provide the :c:type:`PyObject\*` version of the attribute management functions.
+provide the :c:expr:`PyObject*` version of the attribute management functions.
The actual need for type-specific attribute handlers almost completely
disappeared starting with Python 2.2, though there are many examples which have
not been updated to use some of the new generic mechanism that is available.
@@ -339,9 +339,9 @@ of ``NULL`` is required.
Type-specific Attribute Management
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-For simplicity, only the :c:type:`char\*` version will be demonstrated here; the
-type of the name parameter is the only difference between the :c:type:`char\*`
-and :c:type:`PyObject\*` flavors of the interface. This example effectively does
+For simplicity, only the :c:expr:`char\*` version will be demonstrated here; the
+type of the name parameter is the only difference between the :c:expr:`char\*`
+and :c:expr:`PyObject*` flavors of the interface. This example effectively does
the same thing as the generic example above, but does not use the generic
support added in Python 2.2. It explains how the handler functions are
called, so that if you do need to extend their functionality, you'll understand
@@ -572,7 +572,7 @@ performance-critical objects (such as numbers).
For an object to be weakly referencable, the extension type must do two things:
-#. Include a :c:type:`PyObject\*` field in the C object structure dedicated to
+#. Include a :c:expr:`PyObject*` field in the C object structure dedicated to
the weak reference mechanism. The object's constructor should leave it
``NULL`` (which is automatic when using the default
:c:member:`~PyTypeObject.tp_alloc`).
@@ -589,7 +589,7 @@ with the required field::
PyObject *weakreflist; /* List of weak references */
} TrivialObject;
-And the corresponding member in the statically-declared type object::
+And the corresponding member in the statically declared type object::
static PyTypeObject TrivialType = {
PyVarObject_HEAD_INIT(NULL, 0)
diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst
index 34c25d1f6f199c..5d4a3f06dd5402 100644
--- a/Doc/extending/newtypes_tutorial.rst
+++ b/Doc/extending/newtypes_tutorial.rst
@@ -24,7 +24,7 @@ The Basics
==========
The :term:`CPython` runtime sees all Python objects as variables of type
-:c:type:`PyObject\*`, which serves as a "base type" for all Python objects.
+:c:expr:`PyObject*`, which serves as a "base type" for all Python objects.
The :c:type:`PyObject` structure itself only contains the object's
:term:`reference count` and a pointer to the object's "type object".
This is where the action is; the type object determines which (C) functions
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 ff83a1b8134b77..9dbfacd73cc6c7 100644
--- a/Doc/faq/design.rst
+++ b/Doc/faq/design.rst
@@ -155,7 +155,7 @@ Why can't I use an assignment in an expression?
Starting in Python 3.8, you can!
-Assignment expressions using the walrus operator `:=` assign a variable in an
+Assignment expressions using the walrus operator ``:=`` assign a variable in an
expression::
while chunk := fp.read(200):
@@ -313,7 +313,7 @@ you're too lazy to define a function.
Functions are already first class objects in Python, and can be declared in a
local scope. Therefore the only advantage of using a lambda instead of a
-locally-defined function is that you don't need to invent a name for the
+locally defined function is that you don't need to invent a name for the
function -- but that's just a local variable to which the function object (which
is exactly the same type of object that a lambda expression yields) is assigned!
@@ -321,11 +321,10 @@ is exactly the same type of object that a lambda expression yields) is assigned!
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
+`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?
@@ -339,8 +338,8 @@ cycles and deletes the objects involved. The :mod:`gc` module provides functions
to perform a garbage collection, obtain debugging statistics, and tune the
collector's parameters.
-Other implementations (such as `Jython `_ or
-`PyPy `_), however, can rely on a different mechanism
+Other implementations (such as `Jython `_ or
+`PyPy `_), however, can rely on a different mechanism
such as a full-blown garbage collector. This difference can cause some
subtle porting problems if your Python code depends on the behavior of the
reference counting implementation.
diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst
index 1d2aca6f4c8d97..bc3080f60ee237 100644
--- a/Doc/faq/extending.rst
+++ b/Doc/faq/extending.rst
@@ -41,18 +41,18 @@ on what you're trying to do.
.. XXX make sure these all work
-`Cython `_ and its relative `Pyrex
-`_ are compilers
+`Cython `_ and its relative `Pyrex
+`_ are compilers
that accept a slightly modified form of Python and generate the corresponding
C code. Cython and Pyrex make it possible to write an extension without having
to learn Python's C API.
If you need to interface to some C or C++ library for which no Python extension
currently exists, you can try wrapping the library's data types and functions
-with a tool such as `SWIG `_. `SIP
+with a tool such as `SWIG `_. `SIP
`__, `CXX
-`_ `Boost
-`_, or `Weave
+`_ `Boost
+`_, or `Weave
`_ are also
alternatives for wrapping C++ libraries.
@@ -286,6 +286,6 @@ Can I create an object class with some methods implemented in C and others in Py
Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`,
:class:`dict`, etc.
-The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html)
+The Boost Python Library (BPL, https://www.boost.org/libs/python/doc/index.html)
provides a way of doing this from C++ (i.e. you can inherit from an extension
class written in C++ using the BPL).
diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst
index bc4130aaa45c89..a9b2622e02ef3b 100644
--- a/Doc/faq/general.rst
+++ b/Doc/faq/general.rst
@@ -54,8 +54,8 @@ commercial use, to sell copies of Python in source or binary form (modified or
unmodified), or to sell products that incorporate Python in some form. We would
still like to know about all commercial use of Python, of course.
-See `the PSF license page `_ to find further
-explanations and a link to the full text of the license.
+See `the license page `_ to find further
+explanations and the full text of the PSF License.
The Python logo is trademarked, and in certain cases permission is required to
use it. Consult `the Trademark Usage Policy
@@ -113,8 +113,8 @@ 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
-programming), software engineering (unit testing, logging, profiling, parsing
+files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP),
+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
of what's available. A wide variety of third-party extensions are also
@@ -125,11 +125,15 @@ find packages of interest to you.
How does the Python version numbering scheme work?
--------------------------------------------------
-Python versions are numbered A.B.C or A.B. A is the major version number -- it
-is only incremented for really major changes in the language. B is the minor
-version number, incremented for less earth-shattering changes. C is the
-micro-level -- it is incremented for each bugfix release. See :pep:`6` for more
-information about bugfix releases.
+Python versions are numbered "A.B.C" or "A.B":
+
+* *A* is the major version number -- it is only incremented for really major
+ changes in the language.
+* *B* is the minor version number -- it is incremented for less earth-shattering
+ changes.
+* *C* is the micro version number -- it is incremented for each bugfix release.
+
+See :pep:`6` for more information about bugfix releases.
Not all releases are bugfix releases. In the run-up to a new major release, a
series of development releases are made, denoted as alpha, beta, or release
@@ -139,12 +143,14 @@ Betas are more stable, preserving existing interfaces but possibly adding new
modules, and release candidates are frozen, making no changes except as needed
to fix critical bugs.
-Alpha, beta and release candidate versions have an additional suffix. The
-suffix for an alpha version is "aN" for some small number N, the suffix for a
-beta version is "bN" for some small number N, and the suffix for a release
-candidate version is "rcN" for some small number N. In other words, all versions
-labeled 2.0aN precede the versions labeled 2.0bN, which precede versions labeled
-2.0rcN, and *those* precede 2.0.
+Alpha, beta and release candidate versions have an additional suffix:
+
+* The suffix for an alpha version is "aN" for some small number *N*.
+* The suffix for a beta version is "bN" for some small number *N*.
+* The suffix for a release candidate version is "rcN" for some small number *N*.
+
+In other words, all versions labeled *2.0aN* precede the versions labeled
+*2.0bN*, which precede versions labeled *2.0rcN*, and *those* precede 2.0.
You may also find version numbers with a "+" suffix, e.g. "2.2+". These are
unreleased versions, built directly from the CPython development repository. In
@@ -182,7 +188,7 @@ at https://docs.python.org/3/. PDF, plain text, and downloadable HTML versions
also available at https://docs.python.org/3/download.html.
The documentation is written in reStructuredText and processed by `the Sphinx
-documentation tool `__. The reStructuredText source for
+documentation tool `__. The reStructuredText source for
the documentation is part of the Python source distribution.
@@ -209,7 +215,7 @@ every day, and Usenet readers are often more able to cope with this volume.
Announcements of new software releases and events can be found in
comp.lang.python.announce, a low-traffic moderated list that receives about five
postings per day. It's available as `the python-announce mailing list
-`_.
+`_.
More info about other mailing lists and newsgroups
can be found at https://www.python.org/community/lists/.
@@ -242,8 +248,8 @@ Are there any published articles about Python that I can reference?
It's probably best to cite your favorite book about Python.
-The very first article about Python was written in 1991 and is now quite
-outdated.
+The `very first article `_ about Python was
+written in 1991 and is now quite outdated.
Guido van Rossum and Jelke de Boer, "Interactively Testing Remote Servers
Using the Python Programming Language", CWI Quarterly, Volume 4, Issue 4
@@ -264,7 +270,7 @@ Where in the world is www.python.org located?
---------------------------------------------
The Python project's infrastructure is located all over the world and is managed
-by the Python Infrastructure Team. Details `here `__.
+by the Python Infrastructure Team. Details `here `__.
Why is it called Python?
@@ -329,8 +335,8 @@ Consulting the proceedings for `past Python conferences
different companies and organizations.
High-profile Python projects include `the Mailman mailing list manager
-`_ and `the Zope application server
-`_. Several Linux distributions, most notably `Red Hat
+`_ and `the Zope application server
+`_. Several Linux distributions, most notably `Red Hat
`_, have written part or all of their installer and
system administration software in Python. Companies that use Python internally
include Google, Yahoo, and Lucasfilm Ltd.
@@ -346,7 +352,7 @@ titled "Python X.Y Release Schedule", where X.Y is a version that hasn't been
publicly released yet.
New development is discussed on `the python-dev mailing list
-`_.
+`_.
Is it reasonable to propose incompatible changes to Python?
@@ -429,7 +435,7 @@ With the interpreter, documentation is never far from the student as they are
programming.
There are also good IDEs for Python. IDLE is a cross-platform IDE for Python
-that is written in Python using Tkinter. PythonWin is a Windows-specific IDE.
+that is written in Python using Tkinter.
Emacs users will be happy to know that there is a very good Python mode for
Emacs. All of these programming environments provide syntax highlighting,
auto-indenting, and access to the interactive interpreter while coding. Consult
diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst
index 86c56d957cdfec..023ffdf0db510a 100644
--- a/Doc/faq/gui.rst
+++ b/Doc/faq/gui.rst
@@ -49,7 +49,7 @@ environment variables.
To get truly stand-alone applications, the Tcl scripts that form the library
have to be integrated into the application as well. One tool supporting that is
SAM (stand-alone modules), which is part of the Tix distribution
-(http://tix.sourceforge.net/).
+(https://tix.sourceforge.net/).
Build Tix with SAM enabled, perform the appropriate call to
:c:func:`Tclsam_init`, etc. inside Python's
diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst
index b9e541c150dc43..597caaa778e1c8 100644
--- a/Doc/faq/library.rst
+++ b/Doc/faq/library.rst
@@ -180,8 +180,8 @@ How do I create documentation from doc strings?
The :mod:`pydoc` module can create HTML from the doc strings in your Python
source code. An alternative for creating API documentation purely from
-docstrings is `epydoc `_. `Sphinx
-`_ can also include docstring content.
+docstrings is `epydoc `_. `Sphinx
+`_ can also include docstring content.
How do I get a single keypress at a time?
@@ -483,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?
@@ -603,7 +609,7 @@ use ``p.read(n)``.
substituted for standard input and output. You will have to use pseudo ttys
("ptys") instead of pipes. Or you can use a Python interface to Don Libes'
"expect" library. A Python extension that interfaces to expect is called
- "expy" and available from http://expectpy.sourceforge.net. A pure Python
+ "expy" and available from https://expectpy.sourceforge.net. A pure Python
solution that works like expect is `pexpect
`_.
@@ -664,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)?
@@ -774,7 +780,7 @@ socket to :meth:`select.select` to check if it's writable.
The :mod:`asyncio` module provides a general purpose single-threaded and
concurrent asynchronous library, which can be used for writing non-blocking
network code.
- The third-party `Twisted `_ library is
+ The third-party `Twisted `_ library is
a popular and feature-rich alternative.
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index f87eaff9531fce..ab5618db84f77e 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -25,8 +25,9 @@ Reference Manual `. You can also write your own debugger by using the code
for pdb as an example.
The IDLE interactive development environment, which is part of the standard
-Python distribution (normally available as Tools/scripts/idle), includes a
-graphical debugger.
+Python distribution (normally available as
+`Tools/scripts/idle3 `_),
+includes a graphical debugger.
PythonWin is a Python IDE that includes a GUI debugger based on pdb. The
PythonWin debugger colors breakpoints and has quite a few cool features such as
@@ -35,7 +36,7 @@ debugging non-PythonWin programs. PythonWin is available as part of
as a part of the
`ActivePython `_ distribution.
-`Eric `_ is an IDE built on PyQt
+`Eric `_ is an IDE built on PyQt
and the Scintilla editing component.
`trepan3k `_ is a gdb-like debugger.
@@ -56,11 +57,11 @@ 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.
-Static type checkers such as `Mypy `_,
+Static type checkers such as `Mypy `_,
`Pyre `_, and
`Pytype `_ can check type hints in Python
source code.
@@ -78,7 +79,8 @@ 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; with 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.
@@ -95,11 +97,11 @@ The following packages can help with the creation of console and GUI
executables:
* `Nuitka `_ (Cross-platform)
-* `PyInstaller `_ (Cross-platform)
+* `PyInstaller `_ (Cross-platform)
* `PyOxidizer `_ (Cross-platform)
* `cx_Freeze `_ (Cross-platform)
* `py2app `_ (macOS only)
-* `py2exe `_ (Windows only)
+* `py2exe `_ (Windows only)
Are there coding standards or a style guide for Python programs?
----------------------------------------------------------------
@@ -111,10 +113,12 @@ Yes. The coding style required for standard library modules is documented as
Core Language
=============
+.. _faq-unboundlocalerror:
+
Why am I getting an UnboundLocalError when the variable has a value?
--------------------------------------------------------------------
-It can be a surprise to get the UnboundLocalError in previously working
+It can be a surprise to get the :exc:`UnboundLocalError` in previously working
code when it is modified by adding an assignment statement somewhere in
the body of a function.
@@ -123,6 +127,7 @@ This code:
>>> x = 10
>>> def bar():
... print(x)
+ ...
>>> bar()
10
@@ -133,7 +138,7 @@ works, but this code:
... print(x)
... x += 1
-results in an UnboundLocalError:
+results in an :exc:`!UnboundLocalError`:
>>> foo()
Traceback (most recent call last):
@@ -155,6 +160,7 @@ global:
... global x
... print(x)
... x += 1
+ ...
>>> foobar()
10
@@ -176,6 +182,7 @@ keyword:
... x += 1
... bar()
... print(x)
+ ...
>>> foo()
10
11
@@ -273,7 +280,7 @@ main.py::
import mod
print(config.x)
-Note that using a module is also the basis for implementing the Singleton design
+Note that using a module is also the basis for implementing the singleton design
pattern, for the same reason.
@@ -291,10 +298,10 @@ using multiple imports per line uses less screen space.
It's good practice if you import modules in the following order:
-1. standard library modules -- e.g. ``sys``, ``os``, ``getopt``, ``re``
+1. standard library modules -- e.g. :mod:`sys`, :mod:`os`, :mod:`argparse`, :mod:`re`
2. third-party library modules (anything installed in Python's site-packages
- directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc.
-3. locally-developed modules
+ directory) -- e.g. :mod:`!dateutil`, :mod:`!requests`, :mod:`!PIL.Image`
+3. locally developed modules
It is sometimes necessary to move imports to a function or class to avoid
problems with circular imports. Gordon McMillan says:
@@ -409,8 +416,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
@@ -470,7 +478,7 @@ object ``x`` refers to). After this assignment we have two objects (the ints
Some operations (for example ``y.append(10)`` and ``y.sort()``) mutate the
object, whereas superficially similar operations (for example ``y = y + [10]``
-and ``sorted(y)``) create a new object. In general in Python (and in all cases
+and :func:`sorted(y) `) create a new object. In general in Python (and in all cases
in the standard library) a method that mutates an object will return ``None``
to help avoid getting the two types of operations confused. So if you
mistakenly write ``y.sort()`` thinking it will give you a sorted copy of ``y``,
@@ -643,7 +651,7 @@ Sequences can be copied by slicing::
How can I find the methods or attributes of an object?
------------------------------------------------------
-For an instance x of a user-defined class, ``dir(x)`` returns an alphabetized
+For an instance ``x`` of a user-defined class, :func:`dir(x) ` returns an alphabetized
list of the names containing the instance attributes and methods and attributes
defined by its class.
@@ -668,9 +676,9 @@ callable. Consider the following code::
<__main__.A object at 0x16D07CC>
Arguably the class has a name: even though it is bound to two names and invoked
-through the name B the created instance is still reported as an instance of
-class A. However, it is impossible to say whether the instance's name is a or
-b, since both names are bound to the same value.
+through the name ``B`` the created instance is still reported as an instance of
+class ``A``. However, it is impossible to say whether the instance's name is ``a`` or
+``b``, since both names are bound to the same value.
Generally speaking it should not be necessary for your code to "know the names"
of particular values. Unless you are deliberately writing introspective
@@ -734,7 +742,7 @@ Is it possible to write obfuscated one-liners in Python?
--------------------------------------------------------
Yes. Usually this is done by nesting :keyword:`lambda` within
-:keyword:`!lambda`. See the following three examples, due to Ulf Bartelt::
+:keyword:`!lambda`. See the following three examples, slightly adapted from Ulf Bartelt::
from functools import reduce
@@ -747,7 +755,7 @@ Yes. Usually this is done by nesting :keyword:`lambda` within
f(x,f), range(10))))
# Mandelbrot set
- print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
+ print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+'\n'+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
@@ -770,7 +778,7 @@ What does the slash(/) in the parameter list of a function mean?
A slash in the argument list of a function denotes that the parameters prior to
it are positional-only. Positional-only parameters are the ones without an
-externally-usable name. Upon calling a function that accepts positional-only
+externally usable name. Upon calling a function that accepts positional-only
parameters, arguments are mapped to parameters based solely on their position.
For example, :func:`divmod` is a function that accepts positional-only
parameters. Its documentation looks like this::
@@ -840,7 +848,7 @@ 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::
+a :exc:`SyntaxError` because the period is seen as a decimal point::
>>> 1.__class__
File "", line 1
@@ -886,7 +894,7 @@ leading '0' in a decimal number (except '0').
How do I convert a number to a string?
--------------------------------------
-To convert, e.g., the number 144 to the string '144', use the built-in type
+To convert, e.g., the number ``144`` to the string ``'144'``, use the built-in type
constructor :func:`str`. If you want a hexadecimal or octal representation, use
the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see
the :ref:`f-strings` and :ref:`formatstrings` sections,
@@ -1005,11 +1013,11 @@ Not as such.
For simple input parsing, the easiest approach is usually to split the line into
whitespace-delimited words using the :meth:`~str.split` method of string objects
and then convert decimal strings to numeric values using :func:`int` or
-:func:`float`. ``split()`` supports an optional "sep" parameter which is useful
+:func:`float`. :meth:`!split()` supports an optional "sep" parameter which is useful
if the line uses something other than whitespace as a separator.
For more complicated input parsing, regular expressions are more powerful
-than C's :c:func:`sscanf` and better suited for the task.
+than C's ``sscanf`` and better suited for the task.
What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean?
@@ -1018,6 +1026,46 @@ What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean?
See the :ref:`unicode-howto`.
+.. _faq-programming-raw-string-backslash:
+
+Can I end a raw string with an odd number of backslashes?
+---------------------------------------------------------
+
+A raw string ending with an odd number of backslashes will escape the string's quote::
+
+ >>> r'C:\this\will\not\work\'
+ File "", line 1
+ r'C:\this\will\not\work\'
+ ^
+ SyntaxError: unterminated string literal (detected at line 1)
+
+There are several workarounds for this. One is to use regular strings and double
+the backslashes::
+
+ >>> 'C:\\this\\will\\work\\'
+ 'C:\\this\\will\\work\\'
+
+Another is to concatenate a regular string containing an escaped backslash to the
+raw string::
+
+ >>> r'C:\this\will\work' '\\'
+ 'C:\\this\\will\\work\\'
+
+It is also possible to use :func:`os.path.join` to append a backslash on Windows::
+
+ >>> os.path.join(r'C:\this\will\work', '')
+ 'C:\\this\\will\\work\\'
+
+Note that while a backslash will "escape" a quote for the purposes of
+determining where the raw string ends, no escaping occurs when interpreting the
+value of the raw string. That is, the backslash remains present in the value of
+the raw string::
+
+ >>> r'backslash\'preserved'
+ "backslash\\'preserved"
+
+Also see the specification in the :ref:`language reference `.
+
Performance
===========
@@ -1065,7 +1113,7 @@ performance levels:
detrimental to readability).
If you have reached the limit of what pure Python can allow, there are tools
-to take you further away. For example, `Cython `_ can
+to take you further away. For example, `Cython `_ can
compile a slightly modified version of Python code into a C extension, and
can be used on many different platforms. Cython can take advantage of
compilation (and optional type annotations) to make your code significantly
@@ -1205,15 +1253,16 @@ difference is that a Python list can contain objects of many different types.
The ``array`` module also provides methods for creating arrays of fixed types
with compact representations, but they are slower to index than lists. Also
-note that NumPy and other third party packages define array-like structures with
+note that `NumPy `_
+and other third party packages define array-like structures with
various characteristics as well.
-To get Lisp-style linked lists, you can emulate cons cells using tuples::
+To get Lisp-style linked lists, you can emulate *cons cells* using tuples::
lisp_list = ("like", ("this", ("example", None) ) )
If mutability is desired, you could use lists instead of tuples. Here the
-analogue of lisp car is ``lisp_list[0]`` and the analogue of cdr is
+analogue of a Lisp *car* is ``lisp_list[0]`` and the analogue of *cdr* is
``lisp_list[1]``. Only do this if you're sure you really need to, because it's
usually a lot slower than using Python lists.
@@ -1269,16 +1318,28 @@ use a list comprehension::
A = [[None] * w for i in range(h)]
Or, you can use an extension that provides a matrix datatype; `NumPy
-`_ is the best known.
+`_ is the best known.
-How do I apply a method to a sequence of objects?
--------------------------------------------------
+How do I apply a method or function to a sequence of objects?
+-------------------------------------------------------------
-Use a list comprehension::
+To call a method or function and accumulate the return values is a list,
+a :term:`list comprehension` is an elegant solution::
result = [obj.method() for obj in mylist]
+ result = [function(obj) for obj in mylist]
+
+To just run the method or function without saving the return values,
+a plain :keyword:`for` loop will suffice::
+
+ for obj in mylist:
+ obj.method()
+
+ for obj in mylist:
+ function(obj)
+
.. _faq-augmented-assignment-tuple-error:
Why does a_tuple[i] += ['item'] raise an exception when the addition works?
@@ -1333,11 +1394,12 @@ that even though there was an error, the append worked::
['foo', 'item']
To see why this happens, you need to know that (a) if an object implements an
-``__iadd__`` magic method, it gets called when the ``+=`` augmented assignment
+:meth:`~object.__iadd__` magic method, it gets called when the ``+=`` augmented
+assignment
is executed, and its return value is what gets used in the assignment statement;
-and (b) for lists, ``__iadd__`` is equivalent to calling ``extend`` on the list
+and (b) for lists, :meth:`!__iadd__` is equivalent to calling :meth:`~list.extend` on the list
and returning the list. That's why we say that for lists, ``+=`` is a
-"shorthand" for ``list.extend``::
+"shorthand" for :meth:`!list.extend`::
>>> a_list = []
>>> a_list += [1]
@@ -1362,7 +1424,7 @@ Thus, in our tuple example what is happening is equivalent to::
...
TypeError: 'tuple' object does not support item assignment
-The ``__iadd__`` succeeds, and thus the list is extended, but even though
+The :meth:`!__iadd__` succeeds, and thus the list is extended, but even though
``result`` points to the same object that ``a_tuple[0]`` already points to,
that final assignment still results in an error, because tuples are immutable.
@@ -1439,7 +1501,8 @@ See also :ref:`why-self`.
How do I check if an object is an instance of a given class or of a subclass of it?
-----------------------------------------------------------------------------------
-Use the built-in function ``isinstance(obj, cls)``. You can check if an object
+Use the built-in function :func:`isinstance(obj, cls) `. You can
+check if an object
is an instance of any of a number of classes by providing a tuple instead of a
single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also
check whether an object is one of Python's built-in types, e.g.
@@ -1536,13 +1599,13 @@ Here the ``UpperOut`` class redefines the ``write()`` method to convert the
argument string to uppercase before calling the underlying
``self._outfile.write()`` method. All other methods are delegated to the
underlying ``self._outfile`` object. The delegation is accomplished via the
-``__getattr__`` method; consult :ref:`the language reference `
+:meth:`~object.__getattr__` method; consult :ref:`the language reference `
for more information about controlling attribute access.
Note that for more general cases delegation can get trickier. When attributes
-must be set as well as retrieved, the class must define a :meth:`__setattr__`
+must be set as well as retrieved, the class must define a :meth:`~object.__setattr__`
method too, and it must do so carefully. The basic implementation of
-:meth:`__setattr__` is roughly equivalent to the following::
+:meth:`!__setattr__` is roughly equivalent to the following::
class X:
...
@@ -1550,7 +1613,8 @@ method too, and it must do so carefully. The basic implementation of
self.__dict__[name] = value
...
-Most :meth:`__setattr__` implementations must modify ``self.__dict__`` to store
+Most :meth:`!__setattr__` implementations must modify
+:meth:`self.__dict__ ` to store
local state for self without causing an infinite recursion.
@@ -1688,17 +1752,17 @@ My class defines __del__ but it is not called when I delete the object.
There are several possible reasons for this.
-The del statement does not necessarily call :meth:`__del__` -- it simply
+The :keyword:`del` statement does not necessarily call :meth:`~object.__del__` -- it simply
decrements the object's reference count, and if this reaches zero
-:meth:`__del__` is called.
+:meth:`!__del__` is called.
If your data structures contain circular links (e.g. a tree where each child has
a parent reference and each parent has a list of children) the reference counts
will never go back to zero. Once in a while Python runs an algorithm to detect
such cycles, but the garbage collector might run some time after the last
-reference to your data structure vanishes, so your :meth:`__del__` method may be
+reference to your data structure vanishes, so your :meth:`!__del__` method may be
called at an inconvenient and random time. This is inconvenient if you're trying
-to reproduce a problem. Worse, the order in which object's :meth:`__del__`
+to reproduce a problem. Worse, the order in which object's :meth:`!__del__`
methods are executed is arbitrary. You can run :func:`gc.collect` to force a
collection, but there *are* pathological cases where objects will never be
collected.
@@ -1706,7 +1770,7 @@ collected.
Despite the cycle collector, it's still a good idea to define an explicit
``close()`` method on objects to be called whenever you're done with them. The
``close()`` method can then remove attributes that refer to subobjects. Don't
-call :meth:`__del__` directly -- :meth:`__del__` should call ``close()`` and
+call :meth:`!__del__` directly -- :meth:`!__del__` should call ``close()`` and
``close()`` should make sure that it can be called more than once for the same
object.
@@ -1723,7 +1787,7 @@ and sibling references (if they need them!).
Normally, calling :func:`sys.exc_clear` will take care of this by clearing
the last recorded exception.
-Finally, if your :meth:`__del__` method raises an exception, a warning message
+Finally, if your :meth:`!__del__` method raises an exception, a warning message
is printed to :data:`sys.stderr`.
@@ -1851,8 +1915,8 @@ For example, here is the implementation of
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
+When subclassing an immutable type, override the :meth:`~object.__new__` method
+instead of the :meth:`~object.__init__` method. The latter only runs *after* an
instance is created, which is too late to alter data in an immutable
instance.
@@ -1896,6 +1960,8 @@ The classes can be used like this:
'blog-why-python-rocks'
+.. _faq-cache-method-calls:
+
How do I cache method calls?
----------------------------
@@ -1913,7 +1979,7 @@ 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
+The *lru_cache* approach works with methods that have :term:`hashable`
arguments. It creates a reference to the instance unless special
efforts are made to pass in weak references.
@@ -1952,8 +2018,8 @@ can't be made to work because it cannot detect changes to the
attributes.
To make the *lru_cache* approach work when the *station_id* is mutable,
-the class needs to define the *__eq__* and *__hash__* methods so that
-the cache can detect relevant attribute updates::
+the class needs to define the :meth:`~object.__eq__` and :meth:`~object.__hash__`
+methods so that the cache can detect relevant attribute updates::
class Weather:
"Example with a mutable station identifier"
diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst
index 6b95819c8ee855..c0c92fdbbc84d1 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:
@@ -167,7 +167,7 @@ How can I embed Python into a Windows application?
Embedding the Python interpreter in a Windows app can be summarized as follows:
-1. Do _not_ build Python into your .exe file directly. On Windows, Python must
+1. Do **not** build Python into your .exe file directly. On Windows, Python must
be a DLL to handle importing modules that are themselves DLL's. (This is the
first key undocumented fact.) Instead, link to :file:`python{NN}.dll`; it is
typically installed in ``C:\Windows\System``. *NN* is the Python version, a
@@ -186,15 +186,12 @@ 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
make the app's data and methods available to Python. SWIG will handle just
about all the grungy details for you. The result is C code that you link
- *into* your .exe file (!) You do _not_ have to create a DLL file, and this
+ *into* your .exe file (!) You do **not** have to create a DLL file, and this
also simplifies linking.
3. SWIG will create an init function (a C function) whose name depends on the
@@ -221,10 +218,10 @@ Embedding the Python interpreter in a Windows app can be summarized as follows:
5. There are two problems with Python's C API which will become apparent if you
use a compiler other than MSVC, the compiler used to build pythonNN.dll.
- Problem 1: The so-called "Very High Level" functions that take FILE *
+ Problem 1: The so-called "Very High Level" functions that take ``FILE *``
arguments will not work in a multi-compiler environment because each
- compiler's notion of a struct FILE will be different. From an implementation
- standpoint these are very _low_ level functions.
+ compiler's notion of a ``struct FILE`` will be different. From an implementation
+ standpoint these are very low level functions.
Problem 2: SWIG generates the following code when generating wrappers to void
functions:
@@ -280,3 +277,10 @@ Use the :mod:`msvcrt` module. This is a standard Windows-specific extension mod
It defines a function ``kbhit()`` which checks whether a keyboard hit is
present, and ``getch()`` which gets one character without echoing it.
+How do I solve the missing api-ms-win-crt-runtime-l1-1-0.dll error?
+-------------------------------------------------------------------
+
+This can occur on Python 3.5 and later when using Windows 8.1 or earlier without all updates having been installed.
+First ensure your operating system is supported and is up to date, and if that does not resolve the issue,
+visit the `Microsoft support page `_
+for guidance on manually installing the C Runtime update.
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 75db433abd6007..53e8cdcae1cd66 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -136,10 +136,17 @@ Glossary
:exc:`StopAsyncIteration` exception. Introduced by :pep:`492`.
attribute
- A value associated with an object which is referenced by name using
- dotted expressions. For example, if an object *o* has an attribute
+ A value associated with an object which is usually referenced by name
+ using dotted expressions.
+ For example, if an object *o* has an attribute
*a* it would be referenced as *o.a*.
+ It is possible to give an object an attribute whose name is not an
+ identifier as defined by :ref:`identifiers`, for example using
+ :func:`setattr`, if the object allows it.
+ Such an attribute will not be accessible using a dotted expression,
+ and would instead need to be retrieved with :func:`getattr`.
+
awaitable
An object that can be used in an :keyword:`await` expression. Can be
a :term:`coroutine` or an object with an :meth:`__await__` method.
@@ -203,6 +210,16 @@ Glossary
A list of bytecode instructions can be found in the documentation for
:ref:`the dis module `.
+ callable
+ A callable is an object that can be called, possibly with a set
+ of arguments (see :term:`argument`), with the following syntax::
+
+ callable(argument1, argument2, argumentN)
+
+ A :term:`function`, and by extension a :term:`method`, is a callable.
+ An instance of a class that implements the :meth:`~object.__call__`
+ method is also a callable.
+
callback
A subroutine function which is passed as an argument to be executed at
some point in the future.
@@ -532,7 +549,7 @@ Glossary
machines.
However, some extension modules, either standard or third-party,
- are designed so as to release the GIL when doing computationally-intensive
+ are designed so as to release the GIL when doing computationally intensive
tasks such as compression or hashing. Also, the GIL is always released
when doing I/O.
@@ -566,9 +583,9 @@ Glossary
from their :func:`id`.
IDLE
- An Integrated Development Environment for Python. IDLE is a basic editor
- and interpreter environment which ships with the standard distribution of
- Python.
+ An Integrated Development and Learning Environment for Python.
+ :ref:`idle` is a basic editor and interpreter environment
+ which ships with the standard distribution of Python.
immutable
An object with a fixed value. Immutable objects include numbers, strings and
@@ -865,7 +882,7 @@ Glossary
package
A Python :term:`module` which can contain submodules or recursively,
- subpackages. Technically, a package is a Python module with an
+ subpackages. Technically, a package is a Python module with a
``__path__`` attribute.
See also :term:`regular package` and :term:`namespace package`.
@@ -1125,7 +1142,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 2bc2f2d4c839e2..472069032d6509 100644
--- a/Doc/howto/annotations.rst
+++ b/Doc/howto/annotations.rst
@@ -57,6 +57,12 @@ Accessing The Annotations Dict Of An Object In Python 3.10 And Newer
newer is to call :func:`getattr` with three arguments,
for example ``getattr(o, '__annotations__', None)``.
+ Before Python 3.10, accessing ``__annotations__`` on a class that
+ defines no annotations but that has a parent class with
+ annotations would return the parent's ``__annotations__``.
+ In Python 3.10 and newer, the child class's annotations
+ will be an empty dict instead.
+
Accessing The Annotations Dict Of An Object In Python 3.9 And Older
===================================================================
diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst
index a97d10cfe6bb69..9ea140c41a09c7 100644
--- a/Doc/howto/argparse.rst
+++ b/Doc/howto/argparse.rst
@@ -1,10 +1,12 @@
+.. _argparse-tutorial:
+
*****************
Argparse Tutorial
*****************
:author: Tshepang Lekhonkhobe
-.. _argparse-tutorial:
+.. currentmodule:: argparse
This tutorial is intended to be a gentle introduction to :mod:`argparse`, the
recommended command-line parsing module in the Python standard library.
@@ -12,7 +14,7 @@ recommended command-line parsing module in the Python standard library.
.. note::
There are two other modules that fulfill the same task, namely
- :mod:`getopt` (an equivalent for :c:func:`getopt` from the C
+ :mod:`getopt` (an equivalent for ``getopt()`` from the C
language) and the deprecated :mod:`optparse`.
Note also that :mod:`argparse` is based on :mod:`optparse`,
and therefore very similar in terms of usage.
@@ -137,13 +139,13 @@ And running the code:
Here is what's happening:
-* We've added the :meth:`add_argument` method, which is what we use to specify
+* We've added the :meth:`~ArgumentParser.add_argument` method, which is what we use to specify
which command-line options the program is willing to accept. In this case,
I've named it ``echo`` so that it's in line with its function.
* Calling our program now requires us to specify an option.
-* The :meth:`parse_args` method actually returns some data from the
+* The :meth:`~ArgumentParser.parse_args` method actually returns some data from the
options specified, in this case, ``echo``.
* The variable is some form of 'magic' that :mod:`argparse` performs for free
@@ -256,7 +258,7 @@ Here is what is happening:
* To show that the option is actually optional, there is no error when running
the program without it. Note that by default, if an optional argument isn't
- used, the relevant variable, in this case :attr:`args.verbosity`, is
+ used, the relevant variable, in this case ``args.verbosity``, is
given ``None`` as a value, which is the reason it fails the truth
test of the :keyword:`if` statement.
@@ -299,7 +301,7 @@ Here is what is happening:
We even changed the name of the option to match that idea.
Note that we now specify a new keyword, ``action``, and give it the value
``"store_true"``. This means that, if the option is specified,
- assign the value ``True`` to :data:`args.verbose`.
+ assign the value ``True`` to ``args.verbose``.
Not specifying it implies ``False``.
* It complains when you specify a value, in true spirit of what flags
@@ -669,7 +671,7 @@ Conflicting options
So far, we have been working with two methods of an
:class:`argparse.ArgumentParser` instance. Let's introduce a third one,
-:meth:`add_mutually_exclusive_group`. It allows for us to specify options that
+:meth:`~ArgumentParser.add_mutually_exclusive_group`. It allows for us to specify options that
conflict with each other. Let's also change the rest of the program so that
the new functionality makes more sense:
we'll introduce the ``--quiet`` option,
@@ -732,9 +734,9 @@ your program, just in case they don't know::
if args.quiet:
print(answer)
elif args.verbose:
- print("{} to the power {} equals {}".format(args.x, args.y, answer))
+ print(f"{args.x} to the power {args.y} equals {answer}")
else:
- print("{}^{} == {}".format(args.x, args.y, answer))
+ print(f"{args.x}^{args.y} == {answer}")
Note that slight difference in the usage text. Note the ``[-v | -q]``,
which tells us that we can either use ``-v`` or ``-q``,
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 04b1a2cac0b042..c4bf6ef764777a 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -1,5 +1,7 @@
.. highlight:: c
+.. _howto-clinic:
+
**********************
Argument Clinic How-To
**********************
@@ -541,7 +543,7 @@ Let's dive in!
16. Compile, then run the relevant portions of the regression-test suite.
This change should not introduce any new compile-time warnings or errors,
- and there should be no externally-visible change to Python's behavior.
+ and there should be no externally visible change to Python's behavior.
Well, except for one difference: ``inspect.signature()`` run on your function
should now provide a valid signature!
@@ -1023,19 +1025,36 @@ you're not permitted to use:
Using a return converter
------------------------
-By default the impl function Argument Clinic generates for you returns ``PyObject *``.
-But your C function often computes some C type, then converts it into the ``PyObject *``
+By default, the impl function Argument Clinic generates for you returns
+:c:type:`PyObject * `.
+But your C function often computes some C type,
+then converts it into the :c:type:`!PyObject *`
at the last moment. Argument Clinic handles converting your inputs from Python types
into native C types—why not have it convert your return value from a native C type
into a Python type too?
That's what a "return converter" does. It changes your impl function to return
some C type, then adds code to the generated (non-impl) function to handle converting
-that value into the appropriate ``PyObject *``.
+that value into the appropriate :c:type:`!PyObject *`.
The syntax for return converters is similar to that of parameter converters.
You specify the return converter like it was a return annotation on the
-function itself. Return converters behave much the same as parameter converters;
+function itself, using ``->`` notation.
+
+For example:
+
+.. code-block:: c
+
+ /*[clinic input]
+ add -> int
+
+ a: int
+ b: int
+ /
+
+ [clinic start generated code]*/
+
+Return converters behave much the same as parameter converters;
they take arguments, the arguments are all keyword-only, and if you're not changing
any of the default arguments you can omit the parentheses.
@@ -1056,19 +1075,17 @@ Currently Argument Clinic supports only a few return converters:
.. code-block:: none
bool
+ double
+ float
int
- unsigned int
long
- unsigned int
- size_t
Py_ssize_t
- float
- double
- DecodeFSDefault
+ size_t
+ unsigned int
+ unsigned long
-None of these take parameters. For the first three, return -1 to indicate
-error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL``
-pointer to indicate an error.
+None of these take parameters.
+For all of these, return ``-1`` to indicate error.
(There's also an experimental ``NoneType`` converter, which lets you
return ``Py_None`` on success or ``NULL`` on failure, without having
@@ -1117,7 +1134,7 @@ Here's the syntax for cloning a function::
``module.class`` in the sample just to illustrate that you must
use the full path to *both* functions.)
-Sorry, there's no syntax for partially-cloning a function, or cloning a function
+Sorry, there's no syntax for partially cloning a function, or cloning a function
then modifying it. Cloning is an all-or nothing proposition.
Also, the function you are cloning from must have been previously defined
@@ -1315,7 +1332,7 @@ to specify in your subclass. Here's the current list:
there is no default, but not specifying a default may
result in an "uninitialized variable" warning. This can
easily happen when using option groups—although
- properly-written code will never actually use this value,
+ properly written code will never actually use this value,
the variable does get passed in to the impl, and the
C compiler will complain about the "use" of the
uninitialized value. This value should always be a
@@ -1347,7 +1364,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/cporting.rst b/Doc/howto/cporting.rst
index ce7700fc599062..7773620b40b973 100644
--- a/Doc/howto/cporting.rst
+++ b/Doc/howto/cporting.rst
@@ -22,5 +22,5 @@ We recommend the following resources for porting extension modules to Python 3:
.. _Migrating C extensions: http://python3porting.com/cextensions.html
.. _Porting guide: https://py3c.readthedocs.io/en/latest/guide.html
-.. _Cython: http://cython.org/
+.. _Cython: https://cython.org/
.. _CFFI: https://cffi.readthedocs.io/en/latest/
diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst
index 26c4ece5ae6df4..a3068d86d85bc4 100644
--- a/Doc/howto/curses.rst
+++ b/Doc/howto/curses.rst
@@ -4,6 +4,8 @@
Curses Programming with Python
**********************************
+.. currentmodule:: curses
+
:Author: A.M. Kuchling, Eric S. Raymond
:Release: 2.04
@@ -65,7 +67,7 @@ The Python module is a fairly simple wrapper over the C functions provided by
curses; if you're already familiar with curses programming in C, it's really
easy to transfer that knowledge to Python. The biggest difference is that the
Python interface makes things simpler by merging different C functions such as
-:c:func:`addstr`, :c:func:`mvaddstr`, and :c:func:`mvwaddstr` into a single
+:c:func:`!addstr`, :c:func:`!mvaddstr`, and :c:func:`!mvwaddstr` into a single
:meth:`~curses.window.addstr` method. You'll see this covered in more
detail later.
@@ -82,7 +84,7 @@ Before doing anything, curses must be initialized. This is done by
calling the :func:`~curses.initscr` function, which will determine the
terminal type, send any required setup codes to the terminal, and
create various internal data structures. If successful,
-:func:`initscr` returns a window object representing the entire
+:func:`!initscr` returns a window object representing the entire
screen; this is usually called ``stdscr`` after the name of the
corresponding C variable. ::
@@ -151,8 +153,8 @@ importing the :func:`curses.wrapper` function and using it like this::
The :func:`~curses.wrapper` function takes a callable object and does the
initializations described above, also initializing colors if color
-support is present. :func:`wrapper` then runs your provided callable.
-Once the callable returns, :func:`wrapper` will restore the original
+support is present. :func:`!wrapper` then runs your provided callable.
+Once the callable returns, :func:`!wrapper` will restore the original
state of the terminal. The callable is called inside a
:keyword:`try`...\ :keyword:`except` that catches exceptions, restores
the state of the terminal, and then re-raises the exception. Therefore
@@ -200,7 +202,7 @@ This is because curses was originally written with slow 300-baud
terminal connections in mind; with these terminals, minimizing the
time required to redraw the screen was very important. Instead curses
accumulates changes to the screen and displays them in the most
-efficient manner when you call :meth:`refresh`. For example, if your
+efficient manner when you call :meth:`!refresh`. For example, if your
program displays some text in a window and then clears the window,
there's no need to send the original text because they're never
visible.
@@ -210,7 +212,7 @@ really complicate programming with curses much. Most programs go into a flurry
of activity, and then pause waiting for a keypress or some other action on the
part of the user. All you have to do is to be sure that the screen has been
redrawn before pausing to wait for user input, by first calling
-``stdscr.refresh()`` or the :meth:`refresh` method of some other relevant
+:meth:`!stdscr.refresh` or the :meth:`!refresh` method of some other relevant
window.
A pad is a special case of a window; it can be larger than the actual display
@@ -234,7 +236,7 @@ displayed. ::
# : filled with pad content.
pad.refresh( 0,0, 5,5, 20,75)
-The :meth:`refresh` call displays a section of the pad in the rectangle
+The :meth:`!refresh` call displays a section of the pad in the rectangle
extending from coordinate (5,5) to coordinate (20,75) on the screen; the upper
left corner of the displayed section is coordinate (0,0) on the pad. Beyond
that difference, pads are exactly like ordinary windows and support the same
@@ -242,7 +244,7 @@ methods.
If you have multiple windows and pads on screen there is a more
efficient way to update the screen and prevent annoying screen flicker
-as each part of the screen gets updated. :meth:`refresh` actually
+as each part of the screen gets updated. :meth:`!refresh` actually
does two things:
1) Calls the :meth:`~curses.window.noutrefresh` method of each window
@@ -251,8 +253,8 @@ does two things:
2) Calls the function :func:`~curses.doupdate` function to change the
physical screen to match the desired state recorded in the data structure.
-Instead you can call :meth:`noutrefresh` on a number of windows to
-update the data structure, and then call :func:`doupdate` to update
+Instead you can call :meth:`!noutrefresh` on a number of windows to
+update the data structure, and then call :func:`!doupdate` to update
the screen.
@@ -261,11 +263,11 @@ Displaying Text
From a C programmer's point of view, curses may sometimes look like a
twisty maze of functions, all subtly different. For example,
-:c:func:`addstr` displays a string at the current cursor location in
-the ``stdscr`` window, while :c:func:`mvaddstr` moves to a given y,x
-coordinate first before displaying the string. :c:func:`waddstr` is just
-like :c:func:`addstr`, but allows specifying a window to use instead of
-using ``stdscr`` by default. :c:func:`mvwaddstr` allows specifying both
+:c:func:`!addstr` displays a string at the current cursor location in
+the ``stdscr`` window, while :c:func:`!mvaddstr` moves to a given y,x
+coordinate first before displaying the string. :c:func:`!waddstr` is just
+like :c:func:`!addstr`, but allows specifying a window to use instead of
+using ``stdscr`` by default. :c:func:`!mvwaddstr` allows specifying both
a window and a coordinate.
Fortunately the Python interface hides all these details. ``stdscr``
@@ -298,7 +300,7 @@ the next subsection.
The :meth:`~curses.window.addstr` method takes a Python string or
bytestring as the value to be displayed. The contents of bytestrings
are sent to the terminal as-is. Strings are encoded to bytes using
-the value of the window's :attr:`encoding` attribute; this defaults to
+the value of the window's :attr:`~window.encoding` attribute; this defaults to
the default system encoding as returned by :func:`locale.getencoding`.
The :meth:`~curses.window.addch` methods take a character, which can be
@@ -444,15 +446,15 @@ There are two methods for getting input from a window:
It's possible to not wait for the user using the
:meth:`~curses.window.nodelay` window method. After ``nodelay(True)``,
-:meth:`getch` and :meth:`getkey` for the window become
-non-blocking. To signal that no input is ready, :meth:`getch` returns
-``curses.ERR`` (a value of -1) and :meth:`getkey` raises an exception.
+:meth:`!getch` and :meth:`!getkey` for the window become
+non-blocking. To signal that no input is ready, :meth:`!getch` returns
+``curses.ERR`` (a value of -1) and :meth:`!getkey` raises an exception.
There's also a :func:`~curses.halfdelay` function, which can be used to (in
-effect) set a timer on each :meth:`getch`; if no input becomes
+effect) set a timer on each :meth:`!getch`; if no input becomes
available within a specified delay (measured in tenths of a second),
curses raises an exception.
-The :meth:`getch` method returns an integer; if it's between 0 and 255, it
+The :meth:`!getch` method returns an integer; if it's between 0 and 255, it
represents the ASCII code of the key pressed. Values greater than 255 are
special keys such as Page Up, Home, or the cursor keys. You can compare the
value returned to constants such as :const:`curses.KEY_PPAGE`,
@@ -536,12 +538,12 @@ Patches adding support for these would be welcome; see
`the Python Developer's Guide `_ to
learn more about submitting patches to Python.
-* `Writing Programs with NCURSES `_:
+* `Writing Programs with NCURSES `_:
a lengthy tutorial for C programmers.
* `The ncurses man page `_
-* `The ncurses FAQ `_
+* `The ncurses FAQ `_
* `"Use curses... don't swear" `_:
video of a PyCon 2013 talk on controlling terminals using curses or Urwid.
-* `"Console Applications with Urwid" `_:
+* `"Console Applications with Urwid" `_:
video of a PyCon CA 2012 talk demonstrating some applications written using
Urwid.
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index 5e9b110f0fe254..3688c47f0d6ec9 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -582,11 +582,18 @@ a pure Python equivalent:
.. testcode::
+ def find_name_in_mro(cls, name, default):
+ "Emulate _PyType_Lookup() in Objects/typeobject.c"
+ for base in cls.__mro__:
+ if name in vars(base):
+ return vars(base)[name]
+ return default
+
def object_getattribute(obj, name):
"Emulate PyObject_GenericGetAttr() in Objects/object.c"
null = object()
objtype = type(obj)
- cls_var = getattr(objtype, name, null)
+ cls_var = find_name_in_mro(objtype, name, null)
descr_get = getattr(type(cls_var), '__get__', null)
if descr_get is not null:
if (hasattr(type(cls_var), '__set__')
@@ -663,6 +670,15 @@ a pure Python equivalent:
def __getattr__(self, name):
return ('getattr_hook', self, name)
+ class D1:
+ def __get__(self, obj, objtype=None):
+ return type(self), obj, objtype
+
+ class U1:
+ x = D1()
+
+ class U2(U1):
+ pass
.. doctest::
:hide:
@@ -696,6 +712,10 @@ a pure Python equivalent:
>>> b.g == b['g'] == ('getattr_hook', b, 'g')
True
+ >>> u2 = U2()
+ >>> object_getattribute(u2, 'x') == u2.x == (D1, u2, U2)
+ 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.
@@ -827,7 +847,7 @@ afterwards, :meth:`__set_name__` will need to be called manually.
ORM example
-----------
-The following code is simplified skeleton showing how data descriptors could
+The following code is a simplified skeleton showing how data descriptors could
be used to implement an `object relational mapping
`_.
@@ -1253,11 +1273,14 @@ Using the non-data descriptor protocol, a pure Python version of
.. testcode::
+ import functools
+
class StaticMethod:
"Emulate PyStaticMethod_Type() in Objects/funcobject.c"
def __init__(self, f):
self.f = f
+ functools.update_wrapper(self, f)
def __get__(self, obj, objtype=None):
return self.f
@@ -1265,13 +1288,19 @@ Using the non-data descriptor protocol, a pure Python version of
def __call__(self, *args, **kwds):
return self.f(*args, **kwds)
+The :func:`functools.update_wrapper` call adds a ``__wrapped__`` attribute
+that refers to the underlying function. Also it carries forward
+the attributes necessary to make the wrapper look like the wrapped
+function: ``__name__``, ``__qualname__``, ``__doc__``, and ``__annotations__``.
+
.. testcode::
:hide:
class E_sim:
@StaticMethod
- def f(x):
- return x * 10
+ def f(x: int) -> str:
+ "Simple function example"
+ return "!" * x
wrapped_ord = StaticMethod(ord)
@@ -1279,11 +1308,51 @@ Using the non-data descriptor protocol, a pure Python version of
:hide:
>>> E_sim.f(3)
- 30
+ '!!!'
>>> E_sim().f(3)
- 30
+ '!!!'
+
+ >>> sm = vars(E_sim)['f']
+ >>> type(sm).__name__
+ 'StaticMethod'
+ >>> f = E_sim.f
+ >>> type(f).__name__
+ 'function'
+ >>> sm.__name__
+ 'f'
+ >>> f.__name__
+ 'f'
+ >>> sm.__qualname__
+ 'E_sim.f'
+ >>> f.__qualname__
+ 'E_sim.f'
+ >>> sm.__doc__
+ 'Simple function example'
+ >>> f.__doc__
+ 'Simple function example'
+ >>> sm.__annotations__
+ {'x': , 'return': }
+ >>> f.__annotations__
+ {'x': , 'return': }
+ >>> sm.__module__ == f.__module__
+ True
+ >>> sm(3)
+ '!!!'
+ >>> f(3)
+ '!!!'
+
>>> wrapped_ord('A')
65
+ >>> wrapped_ord.__module__ == ord.__module__
+ True
+ >>> wrapped_ord.__wrapped__ == ord
+ True
+ >>> wrapped_ord.__name__ == ord.__name__
+ True
+ >>> wrapped_ord.__qualname__ == ord.__qualname__
+ True
+ >>> wrapped_ord.__doc__ == ord.__doc__
+ True
Class methods
@@ -1339,11 +1408,14 @@ Using the non-data descriptor protocol, a pure Python version of
.. testcode::
+ import functools
+
class ClassMethod:
"Emulate PyClassMethod_Type() in Objects/funcobject.c"
def __init__(self, f):
self.f = f
+ functools.update_wrapper(self, f)
def __get__(self, obj, cls=None):
if cls is None:
@@ -1360,8 +1432,9 @@ Using the non-data descriptor protocol, a pure Python version of
# Verify the emulation works
class T:
@ClassMethod
- def cm(cls, x, y):
- return (cls, x, y)
+ def cm(cls, x: int, y: str) -> tuple[str, int, str]:
+ "Class method that returns a tuple"
+ return (cls.__name__, x, y)
@ClassMethod
@property
@@ -1373,17 +1446,40 @@ Using the non-data descriptor protocol, a pure Python version of
:hide:
>>> T.cm(11, 22)
- (, 11, 22)
+ ('T', 11, 22)
# Also call it from an instance
>>> t = T()
>>> t.cm(11, 22)
- (, 11, 22)
+ ('T', 11, 22)
# Check the alternate path for chained descriptors
>>> T.__doc__
"A doc for 'T'"
+ # Verify that T uses our emulation
+ >>> type(vars(T)['cm']).__name__
+ 'ClassMethod'
+
+ # Verify that update_wrapper() correctly copied attributes
+ >>> T.cm.__name__
+ 'cm'
+ >>> T.cm.__qualname__
+ 'T.cm'
+ >>> T.cm.__doc__
+ 'Class method that returns a tuple'
+ >>> T.cm.__annotations__
+ {'x': , 'y': , 'return': tuple[str, int, str]}
+
+ # Verify that __wrapped__ was added and works correctly
+ >>> f = vars(T)['cm'].__wrapped__
+ >>> type(f).__name__
+ 'function'
+ >>> f.__name__
+ 'cm'
+ >>> f(T, 11, 22)
+ ('T', 11, 22)
+
The code path for ``hasattr(type(self.f), '__get__')`` was added in
Python 3.9 and makes it possible for :func:`classmethod` to support
@@ -1403,6 +1499,12 @@ chained together. In Python 3.11, this functionality was deprecated.
>>> G.__doc__
"A doc for 'G'"
+The :func:`functools.update_wrapper` call in ``ClassMethod`` adds a
+``__wrapped__`` attribute that refers to the underlying function. Also
+it carries forward the attributes necessary to make the wrapper look
+like the wrapped function: ``__name__``, ``__qualname__``, ``__doc__``,
+and ``__annotations__``.
+
Member objects and __slots__
----------------------------
@@ -1515,6 +1617,8 @@ by member descriptors:
def __get__(self, obj, objtype=None):
'Emulate member_get() in Objects/descrobject.c'
# Also see PyMember_GetOne() in Python/structmember.c
+ if obj is None:
+ return self
value = obj._slotvalues[self.offset]
if value is null:
raise AttributeError(self.name)
@@ -1543,13 +1647,13 @@ variables:
class Type(type):
'Simulate how the type metaclass adds member objects for slots'
- def __new__(mcls, clsname, bases, mapping):
+ def __new__(mcls, clsname, bases, mapping, **kwargs):
'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):
mapping[name] = Member(name, clsname, offset)
- return type.__new__(mcls, clsname, bases, mapping)
+ return type.__new__(mcls, clsname, bases, mapping, **kwargs)
The :meth:`object.__new__` method takes care of creating instances that have
slots instead of an instance dictionary. Here is a rough simulation in pure
@@ -1560,7 +1664,7 @@ Python:
class Object:
'Simulate how object.__new__() allocates memory for __slots__'
- def __new__(cls, *args):
+ def __new__(cls, *args, **kwargs):
'Emulate object_new() in Objects/typeobject.c'
inst = super().__new__(cls)
if hasattr(cls, 'slot_names'):
@@ -1573,7 +1677,7 @@ Python:
cls = type(self)
if hasattr(cls, 'slot_names') and name not in cls.slot_names:
raise AttributeError(
- f'{type(self).__name__!r} object has no attribute {name!r}'
+ f'{cls.__name__!r} object has no attribute {name!r}'
)
super().__setattr__(name, value)
@@ -1582,7 +1686,7 @@ Python:
cls = type(self)
if hasattr(cls, 'slot_names') and name not in cls.slot_names:
raise AttributeError(
- f'{type(self).__name__!r} object has no attribute {name!r}'
+ f'{cls.__name__!r} object has no attribute {name!r}'
)
super().__delattr__(name)
diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst
index 7b1cf75fa81f08..55f0dfb4c48c38 100644
--- a/Doc/howto/enum.rst
+++ b/Doc/howto/enum.rst
@@ -173,6 +173,7 @@ yourself some work and use :func:`auto()` for the values::
... FRIDAY = auto()
... SATURDAY = auto()
... SUNDAY = auto()
+ ... WEEKEND = SATURDAY | SUNDAY
.. _enum-advanced-tutorial:
@@ -305,6 +306,10 @@ Iterating over the members of an enum does not provide the aliases::
>>> list(Shape)
[, , ]
+ >>> list(Weekday)
+ [, , , , , , ]
+
+Note that the aliases ``Shape.ALIAS_FOR_SQUARE`` and ``Weekday.WEEKEND`` aren't shown.
The special attribute ``__members__`` is a read-only ordered mapping of names
to members. It includes all names defined in the enumeration, including the
@@ -324,6 +329,11 @@ the enumeration members. For example, finding all the aliases::
>>> [name for name, member in Shape.__members__.items() if member.name != name]
['ALIAS_FOR_SQUARE']
+.. note::
+
+ Aliases for flags include values with multiple flags set, such as ``3``,
+ and no flags set, i.e. ``0``.
+
Comparisons
-----------
@@ -361,6 +371,11 @@ below)::
>>> Color.BLUE == 2
False
+.. warning::
+
+ It is possible to reload modules -- if a reloaded module contains
+ enums, they will be recreated, and the new members may not
+ compare identical/equal to the original members.
Allowed members and attributes of enumerations
----------------------------------------------
@@ -751,7 +766,7 @@ flags being set, the boolean evaluation is :data:`False`::
False
Individual flags should have values that are powers of two (1, 2, 4, 8, ...),
-while combinations of flags won't::
+while combinations of flags will not::
>>> class Color(Flag):
... RED = auto()
@@ -822,17 +837,18 @@ Some rules:
4. 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.
-5. %-style formatting: ``%s`` and ``%r`` call the :class:`Enum` class's
+5. A ``data type`` is a mixin that defines :meth:`__new__`.
+6. %-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.
-6. :ref:`Formatted string literals `, :meth:`str.format`,
+7. :ref:`Formatted string literals `, :meth:`str.format`,
and :func:`format` will use the enum's :meth:`__str__` method.
.. note::
Because :class:`IntEnum`, :class:`IntFlag`, and :class:`StrEnum` are
designed to be drop-in replacements for existing constants, their
- :meth:`__str__` method has been reset to their data types
+ :meth:`__str__` method has been reset to their data types'
:meth:`__str__` method.
When to use :meth:`__new__` vs. :meth:`__init__`
@@ -945,23 +961,11 @@ but remain normal attributes.
""""""""""""""""""""
Enum members are instances of their enum class, and are normally accessed as
-``EnumClass.member``. In Python versions ``3.5`` to ``3.10`` you could access
-members from other members -- this practice was discouraged, and in ``3.11``
-:class:`Enum` returns to not allowing it::
-
- >>> class FieldTypes(Enum):
- ... name = 0
- ... value = 1
- ... size = 2
- ...
- >>> FieldTypes.value.size
- Traceback (most recent call last):
- ...
- AttributeError: member has no attribute 'size'
-
+``EnumClass.member``. In certain situations, such as writing custom enum
+behavior, being able to access one member directly from another is useful,
+and is supported.
.. versionchanged:: 3.5
-.. versionchanged:: 3.11
Creating members that are mixed with other data types
@@ -1107,8 +1111,8 @@ example of when ``KEEP`` is needed).
.. _enum-class-differences:
-How are Enums different?
-------------------------
+How are Enums and Flags different?
+----------------------------------
Enums have a custom metaclass that affects many aspects of both derived :class:`Enum`
classes and their instances (members).
@@ -1120,11 +1124,18 @@ 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
+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__`).
+Flag Classes
+^^^^^^^^^^^^
+
+Flags have an expanded view of aliasing: to be canonical, the value of a flag
+needs to be a power-of-two value, and not a duplicate name. So, in addition to the
+:class:`Enum` definition of alias, a flag with no value (a.k.a. ``0``) or with more than one
+power-of-two value (e.g. ``3``) is considered an alias.
Enum Members (aka instances)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1134,9 +1145,35 @@ The most interesting thing about enum members is that they are singletons.
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.
+Flag Members
+^^^^^^^^^^^^
+
+Flag members can be iterated over just like the :class:`Flag` class, and only the
+canonical members will be returned. For example::
+
+ >>> list(Color)
+ [, , ]
+
+(Note that ``BLACK``, ``PURPLE``, and ``WHITE`` do not show up.)
+
+Inverting a flag member returns the corresponding positive value,
+rather than a negative value --- for example::
+
+ >>> ~Color.RED
+
+
+Flag members have a length corresponding to the number of power-of-two values
+they contain. For example::
+
+ >>> len(Color.PURPLE)
+ 2
+
.. _enum-cookbook:
+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
@@ -1310,7 +1347,7 @@ enumerations)::
DuplicateFreeEnum
^^^^^^^^^^^^^^^^^
-Raises an error if a duplicate member name is found instead of creating an
+Raises an error if a duplicate member value is found instead of creating an
alias::
>>> class DuplicateFreeEnum(Enum):
diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst
index 695b9b31a762bd..64f2293b21e2ee 100644
--- a/Doc/howto/functional.rst
+++ b/Doc/howto/functional.rst
@@ -315,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
@@ -335,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
@@ -363,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 )
@@ -734,7 +741,7 @@ further because you risk skipping a discarded element.
The itertools module
====================
-The :mod:`itertools` module contains a number of commonly-used iterators as well
+The :mod:`itertools` module contains a number of commonly used iterators as well
as functions for combining several iterators. This section will introduce the
module's contents by showing small examples.
@@ -987,7 +994,7 @@ requesting iterator-2 and its corresponding key.
The functools module
====================
-The :mod:`functools` module in Python 2.5 contains some higher-order functions.
+The :mod:`functools` module contains some higher-order functions.
A **higher-order function** takes one or more functions as input and returns a
new function. The most useful tool in this module is the
:func:`functools.partial` function.
@@ -1201,14 +1208,14 @@ General
-------
**Structure and Interpretation of Computer Programs**, by Harold Abelson and
-Gerald Jay Sussman with Julie Sussman. Full text at
-https://mitpress.mit.edu/sicp/. In this classic textbook of computer science,
+Gerald Jay Sussman with Julie Sussman. The book can be found at
+https://mitpress.mit.edu/sicp. In this classic textbook of computer science,
chapters 2 and 3 discuss the use of sequences and streams to organize the data
flow inside a program. The book uses Scheme for its examples, but many of the
design approaches described in these chapters are applicable to functional-style
Python code.
-http://www.defmacro.org/ramblings/fp.html: A general introduction to functional
+https://www.defmacro.org/ramblings/fp.html: A general introduction to functional
programming that uses Java examples and has a lengthy historical introduction.
https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry
@@ -1221,7 +1228,7 @@ https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying.
Python-specific
---------------
-http://gnosis.cx/TPiP/: The first chapter of David Mertz's book
+https://gnosis.cx/TPiP/: The first chapter of David Mertz's book
:title-reference:`Text Processing in Python` discusses functional programming
for text processing, in the section titled "Utilizing Higher-Order Functions in
Text Processing".
diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst
index eae8f143ee206f..8a378e6659efc4 100644
--- a/Doc/howto/index.rst
+++ b/Doc/howto/index.rst
@@ -31,4 +31,5 @@ Currently, the HOWTOs are:
clinic.rst
instrumentation.rst
annotations.rst
+ isolating-extensions.rst
diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst
index 4a59ae82f96e2d..4ce15c69dac90b 100644
--- a/Doc/howto/instrumentation.rst
+++ b/Doc/howto/instrumentation.rst
@@ -123,7 +123,7 @@ Sufficiently modern readelf can print the metadata::
Arguments: 8@%rbp 8@%r12 -4@%eax
The above metadata contains information for SystemTap describing how it
-can patch strategically-placed machine code instructions to enable the
+can patch strategically placed machine code instructions to enable the
tracing hooks used by a SystemTap script.
@@ -410,7 +410,7 @@ needing to directly name the static markers:
The following script uses the tapset above to provide a top-like view of all
-running CPython code, showing the top 20 most frequently-entered bytecode
+running CPython code, showing the top 20 most frequently entered bytecode
frames, each second, across the whole system:
.. code-block:: none
diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst
new file mode 100644
index 00000000000000..2eddb582da7c24
--- /dev/null
+++ b/Doc/howto/isolating-extensions.rst
@@ -0,0 +1,536 @@
+.. highlight:: c
+
+***************************
+Isolating Extension Modules
+***************************
+
+.. topic:: Abstract
+
+ Traditionally, state belonging to Python extension modules was kept in C
+ ``static`` variables, which have process-wide scope. This document
+ describes problems of such per-process state and shows a safer way:
+ per-module state.
+
+ The document also describes how to switch to per-module state where
+ possible. This transition involves allocating space for that state, potentially
+ switching from static types to heap types, and—perhaps most
+ importantly—accessing per-module state from code.
+
+
+Who should read this
+====================
+
+This guide is written for maintainers of :ref:`C-API ` extensions
+who would like to make that extension safer to use in applications where
+Python itself is used as a library.
+
+
+Background
+==========
+
+An *interpreter* is the context in which Python code runs. It contains
+configuration (e.g. the import path) and runtime state (e.g. the set of
+imported modules).
+
+Python supports running multiple interpreters in one process. There are
+two cases to think about—users may run interpreters:
+
+- in sequence, with several :c:func:`Py_InitializeEx`/:c:func:`Py_FinalizeEx`
+ cycles, and
+- in parallel, managing "sub-interpreters" using
+ :c:func:`Py_NewInterpreter`/:c:func:`Py_EndInterpreter`.
+
+Both cases (and combinations of them) would be most useful when
+embedding Python within a library. Libraries generally shouldn't make
+assumptions about the application that uses them, which include
+assuming a process-wide "main Python interpreter".
+
+Historically, Python extension modules don't handle this use case well.
+Many extension modules (and even some stdlib modules) use *per-process*
+global state, because C ``static`` variables are extremely easy to use.
+Thus, data that should be specific to an interpreter ends up being shared
+between interpreters. Unless the extension developer is careful, it is very
+easy to introduce edge cases that lead to crashes when a module is loaded in
+more than one interpreter in the same process.
+
+Unfortunately, *per-interpreter* state is not easy to achieve. Extension
+authors tend to not keep multiple interpreters in mind when developing,
+and it is currently cumbersome to test the behavior.
+
+Enter Per-Module State
+----------------------
+
+Instead of focusing on per-interpreter state, Python's C API is evolving
+to better support the more granular *per-module* state.
+This means that C-level data is be attached to a *module object*.
+Each interpreter creates its own module object, keeping the data separate.
+For testing the isolation, multiple module objects corresponding to a single
+extension can even be loaded in a single interpreter.
+
+Per-module state provides an easy way to think about lifetime and
+resource ownership: the extension module will initialize when a
+module object is created, and clean up when it's freed. In this regard,
+a module is just like any other :c:expr:`PyObject *`; there are no "on
+interpreter shutdown" hooks to think—or forget—about.
+
+Note that there are use cases for different kinds of "globals":
+per-process, per-interpreter, per-thread or per-task state.
+With per-module state as the default, these are still possible,
+but you should treat them as exceptional cases:
+if you need them, you should give them additional care and testing.
+(Note that this guide does not cover them.)
+
+
+Isolated Module Objects
+-----------------------
+
+The key point to keep in mind when developing an extension module is
+that several module objects can be created from a single shared library.
+For example:
+
+.. code-block:: pycon
+
+ >>> import sys
+ >>> import binascii
+ >>> old_binascii = binascii
+ >>> del sys.modules['binascii']
+ >>> import binascii # create a new module object
+ >>> old_binascii == binascii
+ False
+
+As a rule of thumb, the two modules should be completely independent.
+All objects and state specific to the module should be encapsulated
+within the module object, not shared with other module objects, and
+cleaned up when the module object is deallocated.
+Since this just is a rule of thumb, exceptions are possible
+(see `Managing Global State`_), but they will need more
+thought and attention to edge cases.
+
+While some modules could do with less stringent restrictions, isolated
+modules make it easier to set clear expectations and guidelines that
+work across a variety of use cases.
+
+
+Surprising Edge Cases
+---------------------
+
+Note that isolated modules do create some surprising edge cases. Most
+notably, each module object will typically not share its classes and
+exceptions with other similar modules. Continuing from the
+`example above `__,
+note that ``old_binascii.Error`` and ``binascii.Error`` are
+separate objects. In the following code, the exception is *not* caught:
+
+.. code-block:: pycon
+
+ >>> old_binascii.Error == binascii.Error
+ False
+ >>> try:
+ ... old_binascii.unhexlify(b'qwertyuiop')
+ ... except binascii.Error:
+ ... print('boo')
+ ...
+ Traceback (most recent call last):
+ File "", line 2, in
+ binascii.Error: Non-hexadecimal digit found
+
+This is expected. Notice that pure-Python modules behave the same way:
+it is a part of how Python works.
+
+The goal is to make extension modules safe at the C level, not to make
+hacks behave intuitively. Mutating ``sys.modules`` "manually" counts
+as a hack.
+
+
+Making Modules Safe with Multiple Interpreters
+==============================================
+
+
+Managing Global State
+---------------------
+
+Sometimes, the state associated with a Python module is not specific to that module, but
+to the entire process (or something else "more global" than a module).
+For example:
+
+- The ``readline`` module manages *the* terminal.
+- A module running on a circuit board wants to control *the* on-board
+ LED.
+
+In these cases, the Python module should provide *access* to the global
+state, rather than *own* it. If possible, write the module so that
+multiple copies of it can access the state independently (along with
+other libraries, whether for Python or other languages). If that is not
+possible, consider explicit locking.
+
+If it is necessary to use process-global state, the simplest way to
+avoid issues with multiple interpreters is to explicitly prevent a
+module from being loaded more than once per process—see
+`Opt-Out: Limiting to One Module Object per Process`_.
+
+
+Managing Per-Module State
+-------------------------
+
+To use per-module state, use
+:ref:`multi-phase extension module initialization `.
+This signals that your module supports multiple interpreters correctly.
+
+Set ``PyModuleDef.m_size`` to a positive number to request that many
+bytes of storage local to the module. Usually, this will be set to the
+size of some module-specific ``struct``, which can store all of the
+module's C-level state. In particular, it is where you should put
+pointers to classes (including exceptions, but excluding static types)
+and settings (e.g. ``csv``'s :py:data:`~csv.field_size_limit`)
+which the C code needs to function.
+
+.. note::
+ Another option is to store state in the module's ``__dict__``,
+ but you must avoid crashing when users modify ``__dict__`` from
+ Python code. This usually means error- and type-checking at the C level,
+ which is easy to get wrong and hard to test sufficiently.
+
+ However, if module state is not needed in C code, storing it in
+ ``__dict__`` only is a good idea.
+
+If the module state includes ``PyObject`` pointers, the module object
+must hold references to those objects and implement the module-level hooks
+``m_traverse``, ``m_clear`` and ``m_free``. These work like
+``tp_traverse``, ``tp_clear`` and ``tp_free`` of a class. Adding them will
+require some work and make the code longer; this is the price for
+modules which can be unloaded cleanly.
+
+An example of a module with per-module state is currently available as
+`xxlimited `__;
+example module initialization shown at the bottom of the file.
+
+
+Opt-Out: Limiting to One Module Object per Process
+--------------------------------------------------
+
+A non-negative ``PyModuleDef.m_size`` signals that a module supports
+multiple interpreters correctly. If this is not yet the case for your
+module, you can explicitly make your module loadable only once per
+process. For example::
+
+ static int loaded = 0;
+
+ static int
+ exec_module(PyObject* module)
+ {
+ if (loaded) {
+ PyErr_SetString(PyExc_ImportError,
+ "cannot load module more than once per process");
+ return -1;
+ }
+ loaded = 1;
+ // ... rest of initialization
+ }
+
+
+Module State Access from Functions
+----------------------------------
+
+Accessing the state from module-level functions is straightforward.
+Functions get the module object as their first argument; for extracting
+the state, you can use ``PyModule_GetState``::
+
+ static PyObject *
+ func(PyObject *module, PyObject *args)
+ {
+ my_struct *state = (my_struct*)PyModule_GetState(module);
+ if (state == NULL) {
+ return NULL;
+ }
+ // ... rest of logic
+ }
+
+.. note::
+ ``PyModule_GetState`` may return ``NULL`` without setting an
+ exception if there is no module state, i.e. ``PyModuleDef.m_size`` was
+ zero. In your own module, you're in control of ``m_size``, so this is
+ easy to prevent.
+
+
+Heap Types
+==========
+
+Traditionally, types defined in C code are *static*; that is,
+``static PyTypeObject`` structures defined directly in code and
+initialized using ``PyType_Ready()``.
+
+Such types are necessarily shared across the process. Sharing them
+between module objects requires paying attention to any state they own
+or access. To limit the possible issues, static types are immutable at
+the Python level: for example, you can't set ``str.myattribute = 123``.
+
+.. impl-detail::
+ Sharing truly immutable objects between interpreters is fine,
+ as long as they don't provide access to mutable objects.
+ However, in CPython, every Python object has a mutable implementation
+ detail: the reference count. Changes to the refcount are guarded by the GIL.
+ Thus, code that shares any Python objects across interpreters implicitly
+ depends on CPython's current, process-wide GIL.
+
+Because they are immutable and process-global, static types cannot access
+"their" module state.
+If any method of such a type requires access to module state,
+the type must be converted to a *heap-allocated type*, or *heap type*
+for short. These correspond more closely to classes created by Python's
+``class`` statement.
+
+For new modules, using heap types by default is a good rule of thumb.
+
+
+Changing Static Types to Heap Types
+-----------------------------------
+
+Static types can be converted to heap types, but note that
+the heap type API was not designed for "lossless" conversion
+from static types—that is, creating a type that works exactly like a given
+static type.
+So, when rewriting the class definition in a new API,
+you are likely to unintentionally change a few details (e.g. pickleability
+or inherited slots).
+Always test the details that are important to you.
+
+Watch out for the following two points in particular (but note that this is not
+a comprehensive list):
+
+* Unlike static types, heap type objects are mutable by default.
+ Use the :c:data:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability.
+* Heap types inherit :c:member:`~PyTypeObject.tp_new` by default,
+ so it may become possible to instantiate them from Python code.
+ You can prevent this with the :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag.
+
+
+Defining Heap Types
+-------------------
+
+Heap types can be created by filling a :c:struct:`PyType_Spec` structure, a
+description or "blueprint" of a class, and calling
+:c:func:`PyType_FromModuleAndSpec` to construct a new class object.
+
+.. note::
+ Other functions, like :c:func:`PyType_FromSpec`, can also create
+ heap types, but :c:func:`PyType_FromModuleAndSpec` associates the module
+ with the class, allowing access to the module state from methods.
+
+The class should generally be stored in *both* the module state (for
+safe access from C) and the module's ``__dict__`` (for access from
+Python code).
+
+
+Garbage-Collection Protocol
+---------------------------
+
+Instances of heap types hold a reference to their type.
+This ensures that the type isn't destroyed before all its instances are,
+but may result in reference cycles that need to be broken by the
+garbage collector.
+
+To avoid memory leaks, instances of heap types must implement the
+garbage collection protocol.
+That is, heap types should:
+
+- Have the :c:data:`Py_TPFLAGS_HAVE_GC` flag.
+- Define a traverse function using ``Py_tp_traverse``, which
+ visits the type (e.g. using :c:expr:`Py_VISIT(Py_TYPE(self))`).
+
+Please refer to the :ref:`the documentation ` of
+:c:data:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse`
+for additional considerations.
+
+If your traverse function delegates to the ``tp_traverse`` of its base class
+(or another type), ensure that ``Py_TYPE(self)`` is visited only once.
+Note that only heap type are expected to visit the type in ``tp_traverse``.
+
+For example, if your traverse function includes::
+
+ base->tp_traverse(self, visit, arg)
+
+...and ``base`` may be a static type, then it should also include::
+
+ if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ // a heap type's tp_traverse already visited Py_TYPE(self)
+ } else {
+ Py_VISIT(Py_TYPE(self));
+ }
+
+It is not necessary to handle the type's reference count in ``tp_new``
+and ``tp_clear``.
+
+
+Module State Access from Classes
+--------------------------------
+
+If you have a type object defined with :c:func:`PyType_FromModuleAndSpec`,
+you can call :c:func:`PyType_GetModule` to get the associated module, and then
+:c:func:`PyModule_GetState` to get the module's state.
+
+To save a some tedious error-handling boilerplate code, you can combine
+these two steps with :c:func:`PyType_GetModuleState`, resulting in::
+
+ my_struct *state = (my_struct*)PyType_GetModuleState(type);
+ if (state === NULL) {
+ return NULL;
+ }
+
+
+Module State Access from Regular Methods
+----------------------------------------
+
+Accessing the module-level state from methods of a class is somewhat more
+complicated, but is possible thanks to API introduced in Python 3.9.
+To get the state, you need to first get the *defining class*, and then
+get the module state from it.
+
+The largest roadblock is getting *the class a method was defined in*, or
+that method's "defining class" for short. The defining class can have a
+reference to the module it is part of.
+
+Do not confuse the defining class with :c:expr:`Py_TYPE(self)`. If the method
+is called on a *subclass* of your type, ``Py_TYPE(self)`` will refer to
+that subclass, which may be defined in different module than yours.
+
+.. note::
+ The following Python code can illustrate the concept.
+ ``Base.get_defining_class`` returns ``Base`` even
+ if ``type(self) == Sub``:
+
+ .. code-block:: python
+
+ class Base:
+ def get_type_of_self(self):
+ return type(self)
+
+ def get_defining_class(self):
+ return __class__
+
+ class Sub(Base):
+ pass
+
+For a method to get its "defining class", it must use the
+:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS`
+:c:type:`calling convention `
+and the corresponding :c:type:`PyCMethod` signature::
+
+ PyObject *PyCMethod(
+ PyObject *self, // object the method was called on
+ PyTypeObject *defining_class, // defining class
+ PyObject *const *args, // C array of arguments
+ Py_ssize_t nargs, // length of "args"
+ PyObject *kwnames) // NULL, or dict of keyword arguments
+
+Once you have the defining class, call :c:func:`PyType_GetModuleState` to get
+the state of its associated module.
+
+For example::
+
+ static PyObject *
+ example_method(PyObject *self,
+ PyTypeObject *defining_class,
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ PyObject *kwnames)
+ {
+ my_struct *state = (my_struct*)PyType_GetModuleState(defining_class);
+ if (state === NULL) {
+ return NULL;
+ }
+ ... // rest of logic
+ }
+
+ PyDoc_STRVAR(example_method_doc, "...");
+
+ static PyMethodDef my_methods[] = {
+ {"example_method",
+ (PyCFunction)(void(*)(void))example_method,
+ METH_METHOD|METH_FASTCALL|METH_KEYWORDS,
+ example_method_doc}
+ {NULL},
+ }
+
+
+Module State Access from Slot Methods, Getters and Setters
+----------------------------------------------------------
+
+.. note::
+
+ This is new in Python 3.11.
+
+ .. After adding to limited API:
+
+ If you use the :ref:`limited API ,
+ you must update ``Py_LIMITED_API`` to ``0x030b0000``, losing ABI
+ compatibility with earlier versions.
+
+Slot methods—the fast C equivalents for special methods, such as
+:c:member:`~PyNumberMethods.nb_add` for :py:attr:`~object.__add__` or
+:c:member:`~PyType.tp_new` for initialization—have a very simple API that
+doesn't allow passing in the defining class, unlike with :c:type:`PyCMethod`.
+The same goes for getters and setters defined with
+:c:type:`PyGetSetDef`.
+
+To access the module state in these cases, use the
+:c:func:`PyType_GetModuleByDef` function, and pass in the module definition.
+Once you have the module, call :c:func:`PyModule_GetState`
+to get the state::
+
+ PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &module_def);
+ my_struct *state = (my_struct*)PyModule_GetState(module);
+ if (state === NULL) {
+ return NULL;
+ }
+
+``PyType_GetModuleByDef`` works by searching the
+:term:`method resolution order` (i.e. all superclasses) for the first
+superclass that has a corresponding module.
+
+.. note::
+
+ In very exotic cases (inheritance chains spanning multiple modules
+ created from the same definition), ``PyType_GetModuleByDef`` might not
+ return the module of the true defining class. However, it will always
+ return a module with the same definition, ensuring a compatible
+ C memory layout.
+
+
+Lifetime of the Module State
+----------------------------
+
+When a module object is garbage-collected, its module state is freed.
+For each pointer to (a part of) the module state, you must hold a reference
+to the module object.
+
+Usually this is not an issue, because types created with
+:c:func:`PyType_FromModuleAndSpec`, and their instances, hold a reference
+to the module.
+However, you must be careful in reference counting when you reference
+module state from other places, such as callbacks for external
+libraries.
+
+
+Open Issues
+===========
+
+Several issues around per-module state and heap types are still open.
+
+Discussions about improving the situation are best held on the `capi-sig
+mailing list `__.
+
+
+Per-Class Scope
+---------------
+
+It is currently (as of Python 3.11) not possible to attach state to individual
+*types* without relying on CPython implementation details (which may change
+in the future—perhaps, ironically, to allow a proper solution for
+per-class scope).
+
+
+Lossless Conversion to Heap Types
+---------------------------------
+
+The heap type API was not designed for "lossless" conversion from static types;
+that is, creating a type that works exactly like a given static type.
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 704279240b357b..ffb566c1e86db9 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
@@ -218,7 +219,7 @@ messages should not. Here's how you can achieve this::
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
- filename='/temp/myapp.log',
+ filename='/tmp/myapp.log',
filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
@@ -269,6 +270,220 @@ are sent to both destinations.
This example uses console and file handlers, but you can use any number and
combination of handlers you choose.
+Note that the above choice of log filename ``/tmp/myapp.log`` implies use of a
+standard location for temporary files on POSIX systems. On Windows, you may need to
+choose a different directory name for the log - just ensure that the directory exists
+and that you have the permissions to create and update files in it.
+
+
+.. _custom-level-handling:
+
+Custom handling of levels
+-------------------------
+
+Sometimes, you might want to do something slightly different from the standard
+handling of levels in handlers, where all levels above a threshold get
+processed by a handler. To do this, you need to use filters. Let's look at a
+scenario where you want to arrange things as follows:
+
+* Send messages of severity ``INFO`` and ``WARNING`` to ``sys.stdout``
+* Send messages of severity ``ERROR`` and above to ``sys.stderr``
+* Send messages of severity ``DEBUG`` and above to file ``app.log``
+
+Suppose you configure logging with the following JSON:
+
+.. code-block:: json
+
+ {
+ "version": 1,
+ "disable_existing_loggers": false,
+ "formatters": {
+ "simple": {
+ "format": "%(levelname)-8s - %(message)s"
+ }
+ },
+ "handlers": {
+ "stdout": {
+ "class": "logging.StreamHandler",
+ "level": "INFO",
+ "formatter": "simple",
+ "stream": "ext://sys.stdout"
+ },
+ "stderr": {
+ "class": "logging.StreamHandler",
+ "level": "ERROR",
+ "formatter": "simple",
+ "stream": "ext://sys.stderr"
+ },
+ "file": {
+ "class": "logging.FileHandler",
+ "formatter": "simple",
+ "filename": "app.log",
+ "mode": "w"
+ }
+ },
+ "root": {
+ "level": "DEBUG",
+ "handlers": [
+ "stderr",
+ "stdout",
+ "file"
+ ]
+ }
+ }
+
+This configuration does *almost* what we want, except that ``sys.stdout`` would
+show messages of severity ``ERROR`` and above as well as ``INFO`` and
+``WARNING`` messages. To prevent this, we can set up a filter which excludes
+those messages and add it to the relevant handler. This can be configured by
+adding a ``filters`` section parallel to ``formatters`` and ``handlers``:
+
+.. code-block:: json
+
+ {
+ "filters": {
+ "warnings_and_below": {
+ "()" : "__main__.filter_maker",
+ "level": "WARNING"
+ }
+ }
+ }
+
+and changing the section on the ``stdout`` handler to add it:
+
+.. code-block:: json
+
+ {
+ "stdout": {
+ "class": "logging.StreamHandler",
+ "level": "INFO",
+ "formatter": "simple",
+ "stream": "ext://sys.stdout",
+ "filters": ["warnings_and_below"]
+ }
+ }
+
+A filter is just a function, so we can define the ``filter_maker`` (a factory
+function) as follows:
+
+.. code-block:: python
+
+ def filter_maker(level):
+ level = getattr(logging, level)
+
+ def filter(record):
+ return record.levelno <= level
+
+ return filter
+
+This converts the string argument passed in to a numeric level, and returns a
+function which only returns ``True`` if the level of the passed in record is
+at or below the specified level. Note that in this example I have defined the
+``filter_maker`` in a test script ``main.py`` that I run from the command line,
+so its module will be ``__main__`` - hence the ``__main__.filter_maker`` in the
+filter configuration. You will need to change that if you define it in a
+different module.
+
+With the filter added, we can run ``main.py``, which in full is:
+
+.. code-block:: python
+
+ import json
+ import logging
+ import logging.config
+
+ CONFIG = '''
+ {
+ "version": 1,
+ "disable_existing_loggers": false,
+ "formatters": {
+ "simple": {
+ "format": "%(levelname)-8s - %(message)s"
+ }
+ },
+ "filters": {
+ "warnings_and_below": {
+ "()" : "__main__.filter_maker",
+ "level": "WARNING"
+ }
+ },
+ "handlers": {
+ "stdout": {
+ "class": "logging.StreamHandler",
+ "level": "INFO",
+ "formatter": "simple",
+ "stream": "ext://sys.stdout",
+ "filters": ["warnings_and_below"]
+ },
+ "stderr": {
+ "class": "logging.StreamHandler",
+ "level": "ERROR",
+ "formatter": "simple",
+ "stream": "ext://sys.stderr"
+ },
+ "file": {
+ "class": "logging.FileHandler",
+ "formatter": "simple",
+ "filename": "app.log",
+ "mode": "w"
+ }
+ },
+ "root": {
+ "level": "DEBUG",
+ "handlers": [
+ "stderr",
+ "stdout",
+ "file"
+ ]
+ }
+ }
+ '''
+
+ def filter_maker(level):
+ level = getattr(logging, level)
+
+ def filter(record):
+ return record.levelno <= level
+
+ return filter
+
+ logging.config.dictConfig(json.loads(CONFIG))
+ logging.debug('A DEBUG message')
+ logging.info('An INFO message')
+ logging.warning('A WARNING message')
+ logging.error('An ERROR message')
+ logging.critical('A CRITICAL message')
+
+And after running it like this:
+
+.. code-block:: shell
+
+ python main.py 2>stderr.log >stdout.log
+
+We can see the results are as expected:
+
+.. code-block:: shell
+
+ $ more *.log
+ ::::::::::::::
+ app.log
+ ::::::::::::::
+ DEBUG - A DEBUG message
+ INFO - An INFO message
+ WARNING - A WARNING message
+ ERROR - An ERROR message
+ CRITICAL - A CRITICAL message
+ ::::::::::::::
+ stderr.log
+ ::::::::::::::
+ ERROR - An ERROR message
+ CRITICAL - A CRITICAL message
+ ::::::::::::::
+ stdout.log
+ ::::::::::::::
+ INFO - An INFO message
+ WARNING - A WARNING message
+
Configuration server example
----------------------------
@@ -326,6 +541,8 @@ configuration::
print('complete')
+.. _blocking-handlers:
+
Dealing with handlers that block
--------------------------------
@@ -391,6 +608,14 @@ which, when run, will produce:
MainThread: Look out!
+.. note:: Although the earlier discussion wasn't specifically talking about
+ async code, but rather about slow logging handlers, it should be noted that
+ when logging from async code, network and even file handlers could lead to
+ problems (blocking the event loop) because some logging is done from
+ :mod:`asyncio` internals. It might be best, if any async code is used in an
+ application, to use the above approach for logging, so that any blocking code
+ runs only in the ``QueueListener`` thread.
+
.. versionchanged:: 3.5
Prior to Python 3.5, the :class:`QueueListener` always passed every message
received from the queue to every handler it was initialized with. (This was
@@ -544,13 +769,71 @@ 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.
-
+.. _socket-listener-gist: https://gist.github.com/vsajip/4b227eeec43817465ca835ca66f75e2b
+
+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. It consists of the following files:
+
++-------------------------+----------------------------------------------------+
+| File | Purpose |
++=========================+====================================================+
+| :file:`prepare.sh` | A Bash script to prepare the environment for |
+| | testing |
++-------------------------+----------------------------------------------------+
+| :file:`supervisor.conf` | The Supervisor configuration file, which has |
+| | entries for the listener and a multi-process web |
+| | application |
++-------------------------+----------------------------------------------------+
+| :file:`ensure_app.sh` | A Bash script to ensure that Supervisor is running |
+| | with the above configuration |
++-------------------------+----------------------------------------------------+
+| :file:`log_listener.py` | The socket listener program which receives log |
+| | events and records them to a file |
++-------------------------+----------------------------------------------------+
+| :file:`main.py` | A simple web application which performs logging |
+| | via a socket connected to the listener |
++-------------------------+----------------------------------------------------+
+| :file:`webapp.json` | A JSON configuration file for the web application |
++-------------------------+----------------------------------------------------+
+| :file:`client.py` | A Python script to exercise the web application |
++-------------------------+----------------------------------------------------+
+
+The web application uses `Gunicorn `_, which is a
+popular web application server that starts multiple worker processes to handle
+requests. This example setup shows how the workers can write to the same log file
+without conflicting with one another --- they all go through the socket listener.
+
+To test these files, do the following in a POSIX environment:
+
+#. Download `the Gist `__
+ as a ZIP archive using the :guilabel:`Download ZIP` button.
+
+#. Unzip the above files from the archive into a scratch directory.
+
+#. In the scratch directory, run ``bash prepare.sh`` to get things ready.
+ This creates a :file:`run` subdirectory to contain Supervisor-related and
+ log files, and a :file:`venv` subdirectory to contain a virtual environment
+ into which ``bottle``, ``gunicorn`` and ``supervisor`` are installed.
+
+#. Run ``bash ensure_app.sh`` to ensure that Supervisor is running with
+ the above configuration.
+
+#. Run ``venv/bin/python client.py`` to exercise the web application,
+ which will lead to records being written to the log.
+
+#. Inspect the log files in the :file:`run` subdirectory. You should see the
+ most recent log lines in files matching the pattern :file:`app.log*`. They won't be in
+ any particular order, since they have been handled concurrently by different
+ worker processes in a non-deterministic way.
+
+#. You can shut down the listener and the web application by running
+ ``venv/bin/supervisorctl -c supervisor.conf shutdown``.
+
+You may need to tweak the configuration files in the unlikely event that the
+configured ports clash with something else in your test environment.
.. _context-info:
@@ -713,6 +996,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', type=int, 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:
@@ -1455,26 +1986,47 @@ Using a rotator and namer to customize log rotation processing
--------------------------------------------------------------
An example of how you can define a namer and rotator is given in the following
-snippet, which shows zlib-based compression of the log file::
+runnable script, which shows gzip compression of the log file::
+
+ import gzip
+ import logging
+ import logging.handlers
+ import os
+ import shutil
def namer(name):
return name + ".gz"
def rotator(source, dest):
- with open(source, "rb") as sf:
- data = sf.read()
- compressed = zlib.compress(data, 9)
- with open(dest, "wb") as df:
- df.write(compressed)
+ with open(source, 'rb') as f_in:
+ with gzip.open(dest, 'wb') as f_out:
+ shutil.copyfileobj(f_in, f_out)
os.remove(source)
- rh = logging.handlers.RotatingFileHandler(...)
+
+ rh = logging.handlers.RotatingFileHandler('rotated.log', maxBytes=128, backupCount=5)
rh.rotator = rotator
rh.namer = namer
-These are not "true" .gz files, as they are bare compressed data, with no
-"container" such as you’d find in an actual gzip file. This snippet is just
-for illustration purposes.
+ root = logging.getLogger()
+ root.setLevel(logging.INFO)
+ root.addHandler(rh)
+ f = logging.Formatter('%(asctime)s %(message)s')
+ rh.setFormatter(f)
+ for i in range(1000):
+ root.info(f'Message no. {i + 1}')
+
+After running this, you will see six new files, five of which are compressed:
+
+.. code-block:: shell-session
+
+ $ ls rotated.log*
+ rotated.log rotated.log.2.gz rotated.log.4.gz
+ rotated.log.1.gz rotated.log.3.gz rotated.log.5.gz
+ $ zcat rotated.log.1.gz
+ 2023-01-20 02:28:17,767 Message no. 996
+ 2023-01-20 02:28:17,767 Message no. 997
+ 2023-01-20 02:28:17,767 Message no. 998
A more elaborate multiprocessing example
----------------------------------------
@@ -1990,7 +2542,7 @@ should be logged, or the ``extra`` keyword parameter to indicate additional
contextual information to be added to the log). So you cannot directly make
logging calls using :meth:`str.format` or :class:`string.Template` syntax,
because internally the logging package uses %-formatting to merge the format
-string and the variable arguments. There would no changing this while preserving
+string and the variable arguments. There would be no changing this while preserving
backward compatibility, since all logging calls which are out there in existing
code will be using %-format strings.
@@ -2424,13 +2976,95 @@ You can of course use the conventional means of decoration::
...
+.. _buffered-smtp:
+
+Sending logging messages to email, with buffering
+-------------------------------------------------
+
+To illustrate how you can send log messages via email, so that a set number of
+messages are sent per email, you can subclass
+:class:`~logging.handlers.BufferingHandler`. In the following example, which you can
+adapt to suit your specific needs, a simple test harness is provided which allows you
+to run the script with command line arguments specifying what you typically need to
+send things via SMTP. (Run the downloaded script with the ``-h`` argument to see the
+required and optional arguments.)
+
+.. code-block:: python
+
+ import logging
+ import logging.handlers
+ import smtplib
+
+ class BufferingSMTPHandler(logging.handlers.BufferingHandler):
+ def __init__(self, mailhost, port, username, password, fromaddr, toaddrs,
+ subject, capacity):
+ logging.handlers.BufferingHandler.__init__(self, capacity)
+ self.mailhost = mailhost
+ self.mailport = port
+ self.username = username
+ self.password = password
+ self.fromaddr = fromaddr
+ if isinstance(toaddrs, str):
+ toaddrs = [toaddrs]
+ self.toaddrs = toaddrs
+ self.subject = subject
+ self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
+
+ def flush(self):
+ if len(self.buffer) > 0:
+ try:
+ smtp = smtplib.SMTP(self.mailhost, self.mailport)
+ smtp.starttls()
+ smtp.login(self.username, self.password)
+ msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, ','.join(self.toaddrs), self.subject)
+ for record in self.buffer:
+ s = self.format(record)
+ msg = msg + s + "\r\n"
+ smtp.sendmail(self.fromaddr, self.toaddrs, msg)
+ smtp.quit()
+ except Exception:
+ if logging.raiseExceptions:
+ raise
+ self.buffer = []
+
+ if __name__ == '__main__':
+ import argparse
+
+ ap = argparse.ArgumentParser()
+ aa = ap.add_argument
+ aa('host', metavar='HOST', help='SMTP server')
+ aa('--port', '-p', type=int, default=587, help='SMTP port')
+ aa('user', metavar='USER', help='SMTP username')
+ aa('password', metavar='PASSWORD', help='SMTP password')
+ aa('to', metavar='TO', help='Addressee for emails')
+ aa('sender', metavar='SENDER', help='Sender email address')
+ aa('--subject', '-s',
+ default='Test Logging email from Python logging module (buffering)',
+ help='Subject of email')
+ options = ap.parse_args()
+ logger = logging.getLogger()
+ logger.setLevel(logging.DEBUG)
+ h = BufferingSMTPHandler(options.host, options.port, options.user,
+ options.password, options.sender,
+ options.to, options.subject, 10)
+ logger.addHandler(h)
+ for i in range(102):
+ logger.info("Info index = %d", i)
+ h.flush()
+ h.close()
+
+If you run this script and your SMTP server is correctly set up, you should find that
+it sends eleven emails to the addressee you specify. The first ten emails will each
+have ten log messages, and the eleventh will have two messages. That makes up 102
+messages as specified in the script.
+
.. _utc-formatting:
Formatting times using UTC (GMT) via configuration
--------------------------------------------------
Sometimes you want to format times using UTC, which can be done using a class
-such as `UTCFormatter`, shown below::
+such as ``UTCFormatter``, shown below::
import logging
import time
@@ -2995,6 +3629,236 @@ 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)
+
+How to treat a logger like an output stream
+-------------------------------------------
+
+Sometimes, you need to interface to a third-party API which expects a file-like
+object to write to, but you want to direct the API's output to a logger. You
+can do this using a class which wraps a logger with a file-like API.
+Here's a short script illustrating such a class:
+
+.. code-block:: python
+
+ import logging
+
+ class LoggerWriter:
+ def __init__(self, logger, level):
+ self.logger = logger
+ self.level = level
+
+ def write(self, message):
+ if message != '\n': # avoid printing bare newlines, if you like
+ self.logger.log(self.level, message)
+
+ def flush(self):
+ # doesn't actually do anything, but might be expected of a file-like
+ # object - so optional depending on your situation
+ pass
+
+ def close(self):
+ # doesn't actually do anything, but might be expected of a file-like
+ # object - so optional depending on your situation. You might want
+ # to set a flag so that later calls to write raise an exception
+ pass
+
+ def main():
+ logging.basicConfig(level=logging.DEBUG)
+ logger = logging.getLogger('demo')
+ info_fp = LoggerWriter(logger, logging.INFO)
+ debug_fp = LoggerWriter(logger, logging.DEBUG)
+ print('An INFO message', file=info_fp)
+ print('A DEBUG message', file=debug_fp)
+
+ if __name__ == "__main__":
+ main()
+
+When this script is run, it prints
+
+.. code-block:: text
+
+ INFO:demo:An INFO message
+ DEBUG:demo:A DEBUG message
+
+You could also use ``LoggerWriter`` to redirect ``sys.stdout`` and
+``sys.stderr`` by doing something like this:
+
+.. code-block:: python
+
+ import sys
+
+ sys.stdout = LoggerWriter(logger, logging.INFO)
+ sys.stderr = LoggerWriter(logger, logging.WARNING)
+
+You should do this *after* configuring logging for your needs. In the above
+example, the :func:`~logging.basicConfig` call does this (using the
+``sys.stderr`` value *before* it is overwritten by a ``LoggerWriter``
+instance). Then, you'd get this kind of result:
+
+.. code-block:: pycon
+
+ >>> print('Foo')
+ INFO:demo:Foo
+ >>> print('Bar', file=sys.stderr)
+ WARNING:demo:Bar
+ >>>
+
+Of course, the examples above show output according to the format used by
+:func:`~logging.basicConfig`, but you can use a different formatter when you
+configure logging.
+
+Note that with the above scheme, you are somewhat at the mercy of buffering and
+the sequence of write calls which you are intercepting. For example, with the
+definition of ``LoggerWriter`` above, if you have the snippet
+
+.. code-block:: python
+
+ sys.stderr = LoggerWriter(logger, logging.WARNING)
+ 1 / 0
+
+then running the script results in
+
+.. code-block:: text
+
+ WARNING:demo:Traceback (most recent call last):
+
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/test.py", line 53, in
+
+ WARNING:demo:
+ WARNING:demo:main()
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/test.py", line 49, in main
+
+ WARNING:demo:
+ WARNING:demo:1 / 0
+ WARNING:demo:ZeroDivisionError
+ WARNING:demo::
+ WARNING:demo:division by zero
+
+As you can see, this output isn't ideal. That's because the underlying code
+which writes to ``sys.stderr`` makes mutiple writes, each of which results in a
+separate logged line (for example, the last three lines above). To get around
+this problem, you need to buffer things and only output log lines when newlines
+are seen. Let's use a slghtly better implementation of ``LoggerWriter``:
+
+.. code-block:: python
+
+ class BufferingLoggerWriter(LoggerWriter):
+ def __init__(self, logger, level):
+ super().__init__(logger, level)
+ self.buffer = ''
+
+ def write(self, message):
+ if '\n' not in message:
+ self.buffer += message
+ else:
+ parts = message.split('\n')
+ if self.buffer:
+ s = self.buffer + parts.pop(0)
+ self.logger.log(self.level, s)
+ self.buffer = parts.pop()
+ for part in parts:
+ self.logger.log(self.level, part)
+
+This just buffers up stuff until a newline is seen, and then logs complete
+lines. With this approach, you get better output:
+
+.. code-block:: text
+
+ WARNING:demo:Traceback (most recent call last):
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/main.py", line 55, in
+ WARNING:demo: main()
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/main.py", line 52, in main
+ WARNING:demo: 1/0
+ WARNING:demo:ZeroDivisionError: division by zero
+
.. patterns-to-avoid:
@@ -3006,7 +3870,6 @@ 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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -3055,7 +3918,6 @@ 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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -3064,7 +3926,6 @@ 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
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -3075,3 +3936,23 @@ 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 4d76c27332ccd3..f3ed98fd85a077 100644
--- a/Doc/howto/logging.rst
+++ b/Doc/howto/logging.rst
@@ -124,7 +124,7 @@ Logging to a file
^^^^^^^^^^^^^^^^^
A very common situation is that of recording logging events in a file, so let's
-look at that next. Be sure to try the following in a newly-started Python
+look at that next. Be sure to try the following in a newly started Python
interpreter, and don't just continue from the session described above::
import logging
@@ -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,
@@ -335,7 +336,7 @@ favourite beverage and carry on.
If your logging needs are simple, then use the above examples to incorporate
logging into your own scripts, and if you run into problems or don't
understand something, please post a question on the comp.lang.python Usenet
-group (available at https://groups.google.com/forum/#!forum/comp.lang.python) and you
+group (available at https://groups.google.com/g/comp.lang.python) and you
should receive help before too long.
Still here? You can carry on reading the next few sections, which provide a
@@ -414,6 +415,7 @@ The flow of log event information in loggers and handlers is illustrated in the
following diagram.
.. image:: logging_flow.png
+ :class: invert-in-dark-mode
Loggers
^^^^^^^
@@ -551,14 +553,14 @@ raw message. If there is no date format string, the default date format is:
%Y-%m-%d %H:%M:%S
-with the milliseconds tacked on at the end. The ``style`` is one of `%`, '{'
-or '$'. If one of these is not specified, then '%' will be used.
+with the milliseconds tacked on at the end. The ``style`` is one of ``'%'``,
+``'{'``, or ``'$'``. If one of these is not specified, then ``'%'`` will be used.
-If the ``style`` is '%', the message format string uses
+If the ``style`` is ``'%'``, the message format string uses
``%()s`` styled string substitution; the possible keys are
-documented in :ref:`logrecord-attributes`. If the style is '{', the message
+documented in :ref:`logrecord-attributes`. If the style is ``'{'``, the message
format string is assumed to be compatible with :meth:`str.format` (using
-keyword arguments), while if the style is '$' then the message format string
+keyword arguments), while if the style is ``'$'`` then the message format string
should conform to what is expected by :meth:`string.Template.substitute`.
.. versionchanged:: 3.2
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
index abcc34287e3d29..baea3e85c3b84b 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -433,19 +433,19 @@ to make sure everything functions as expected in both versions of Python.
.. _caniusepython3: https://pypi.org/project/caniusepython3
-.. _cheat sheet: http://python-future.org/compatible_idioms.html
+.. _cheat sheet: https://python-future.org/compatible_idioms.html
.. _coverage.py: https://pypi.org/project/coverage
-.. _Futurize: http://python-future.org/automatic_conversion.html
+.. _Futurize: https://python-future.org/automatic_conversion.html
.. _importlib2: https://pypi.org/project/importlib2
.. _Modernize: https://python-modernize.readthedocs.io/
-.. _mypy: http://mypy-lang.org/
+.. _mypy: https://mypy-lang.org/
.. _Porting to Python 3: http://python3porting.com/
.. _Pylint: https://pypi.org/project/pylint
.. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python3/questions_and_answers.html
.. _pytype: https://github.com/google/pytype
-.. _python-future: http://python-future.org/
+.. _python-future: https://python-future.org/
.. _python-porting: https://mail.python.org/pipermail/python-porting/
.. _six: https://pypi.org/project/six
.. _tox: https://pypi.org/project/tox
diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst
index c4eed8fb1fbe72..5cd6140f19ca2e 100644
--- a/Doc/howto/regex.rst
+++ b/Doc/howto/regex.rst
@@ -949,7 +949,7 @@ Additionally, you can retrieve named groups as a dictionary with
>>> m.groupdict()
{'first': 'Jane', 'last': 'Doe'}
-Named groups are handy because they let you use easily-remembered names, instead
+Named groups are handy because they let you use easily remembered names, instead
of having to remember numbers. Here's an example RE from the :mod:`imaplib`
module::
diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst
index e58f78a7cb0245..0bbf97da39768d 100644
--- a/Doc/howto/sockets.rst
+++ b/Doc/howto/sockets.rst
@@ -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 53cbe01e92144b..decce12bf3faf6 100644
--- a/Doc/howto/sorting.rst
+++ b/Doc/howto/sorting.rst
@@ -186,8 +186,8 @@ The `Timsort `_ algorithm used in Python
does multiple sorts efficiently because it can take advantage of any ordering
already present in a dataset.
-The Old Way Using Decorate-Sort-Undecorate
-==========================================
+Decorate-Sort-Undecorate
+========================
This idiom is called Decorate-Sort-Undecorate after its three steps:
@@ -226,90 +226,36 @@ after Randal L. Schwartz, who popularized it among Perl programmers.
Now that Python sorting provides key-functions, this technique is not often needed.
+Comparison Functions
+====================
-The Old Way Using the *cmp* Parameter
-=====================================
-
-Many constructs given in this HOWTO assume Python 2.4 or later. Before that,
-there was no :func:`sorted` builtin and :meth:`list.sort` took no keyword
-arguments. Instead, all of the Py2.x versions supported a *cmp* parameter to
-handle user specified comparison functions.
-
-In Py3.0, the *cmp* parameter was removed entirely (as part of a larger effort to
-simplify and unify the language, eliminating the conflict between rich
-comparisons and the :meth:`__cmp__` magic method).
-
-In Py2.x, sort allowed an optional function which can be called for doing the
-comparisons. That function should take two arguments to be compared and then
-return a negative value for less-than, return zero if they are equal, or return
-a positive value for greater-than. For example, we can do:
-
-.. doctest::
-
- >>> def numeric_compare(x, y):
- ... return x - y
- >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare) # doctest: +SKIP
- [1, 2, 3, 4, 5]
-
-Or you can reverse the order of comparison with:
-
-.. doctest::
-
- >>> def reverse_numeric(x, y):
- ... return y - x
- >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric) # doctest: +SKIP
- [5, 4, 3, 2, 1]
-
-When porting code from Python 2.x to 3.x, the situation can arise when you have
-the user supplying a comparison function and you need to convert that to a key
-function. The following wrapper makes that easy to do:
-
-.. testcode::
-
- def cmp_to_key(mycmp):
- 'Convert a cmp= function into a key= function'
- class K:
- def __init__(self, obj, *args):
- self.obj = obj
- def __lt__(self, other):
- return mycmp(self.obj, other.obj) < 0
- def __gt__(self, other):
- return mycmp(self.obj, other.obj) > 0
- def __eq__(self, other):
- return mycmp(self.obj, other.obj) == 0
- def __le__(self, other):
- return mycmp(self.obj, other.obj) <= 0
- def __ge__(self, other):
- return mycmp(self.obj, other.obj) >= 0
- def __ne__(self, other):
- return mycmp(self.obj, other.obj) != 0
- return K
-
-.. doctest::
- :hide:
+Unlike key functions that return an absolute value for sorting, a comparison
+function computes the relative ordering for two inputs.
- >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
- [5, 4, 3, 2, 1]
+For example, a `balance scale
+`_
+compares two samples giving a relative ordering: lighter, equal, or heavier.
+Likewise, a comparison function such as ``cmp(a, b)`` will return a negative
+value for less-than, zero if the inputs are equal, or a positive value for
+greater-than.
-To convert to a key function, just wrap the old comparison function:
-
-.. testsetup::
-
- from functools import cmp_to_key
-
-.. doctest::
+It is common to encounter comparison functions when translating algorithms from
+other languages. Also, some libraries provide comparison functions as part of
+their API. For example, :func:`locale.strcoll` is a comparison function.
- >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
- [5, 4, 3, 2, 1]
+To accommodate those situations, Python provides
+:class:`functools.cmp_to_key` to wrap the comparison function
+to make it usable as a key function::
-In Python 3.2, the :func:`functools.cmp_to_key` function was added to the
-:mod:`functools` module in the standard library.
+ sorted(words, key=cmp_to_key(strcoll)) # locale-aware sort order
Odds and Ends
=============
* For locale aware sorting, use :func:`locale.strxfrm` for a key function or
- :func:`locale.strcoll` for a comparison function.
+ :func:`locale.strcoll` for a comparison function. This is necessary
+ because "alphabetical" sort orderings can vary across cultures even
+ if the underlying alphabet is the same.
* The *reverse* parameter still maintains sort stability (so that records with
equal keys retain the original order). Interestingly, that effect can be
diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst
index 535b21bd4a54f5..ca09aee72bf879 100644
--- a/Doc/howto/unicode.rst
+++ b/Doc/howto/unicode.rst
@@ -167,7 +167,7 @@ On the Computerphile Youtube channel, Tom Scott briefly
(9 minutes 36 seconds).
To help understand the standard, Jukka Korpela has written `an introductory
-guide `_ to reading the
+guide `_ to reading the
Unicode character tables.
Another `good introductory article `_
@@ -517,7 +517,7 @@ References
Some good alternative discussions of Python's Unicode support are:
-* `Processing Text Files in Python 3 `_, by Nick Coghlan.
+* `Processing Text Files in Python 3 `_, by Nick Coghlan.
* `Pragmatic Unicode `_, a PyCon 2012 presentation by Ned Batchelder.
The :class:`str` type is described in the Python library reference at
@@ -735,7 +735,7 @@ References
----------
One section of `Mastering Python 3 Input/Output
-`_,
+`_,
a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling.
The `PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware
@@ -745,7 +745,7 @@ discuss questions of character encodings as well as how to internationalize
and localize an application. These slides cover Python 2.x only.
`The Guts of Unicode in Python
-`_
+`_
is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode
representation in Python 3.3.
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index 12d525771ddc28..86137fb38c9b93 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -4,14 +4,7 @@
HOWTO Fetch Internet Resources Using The urllib Package
***********************************************************
-:Author: `Michael Foord `_
-
-.. note::
-
- There is a French translation of an earlier revision of this
- HOWTO, available at `urllib2 - Le Manuel manquant
- `_.
-
+:Author: `Michael Foord `_
Introduction
@@ -22,7 +15,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.
@@ -86,7 +79,7 @@ response::
import urllib.request
- req = urllib.request.Request('http://www.voidspace.org.uk')
+ req = urllib.request.Request('http://python.org/')
with urllib.request.urlopen(req) as response:
the_page = response.read()
@@ -411,7 +404,7 @@ fetched, particularly the headers sent by the server. It is currently an
:class:`http.client.HTTPMessage` instance.
Typical headers include 'Content-length', 'Content-type', and so on. See the
-`Quick Reference to HTTP Headers `_
+`Quick Reference to HTTP Headers `_
for a useful listing of HTTP headers with brief explanations of their meaning
and use.
@@ -420,7 +413,7 @@ Openers and Handlers
====================
When you fetch a URL you use an opener (an instance of the perhaps
-confusingly-named :class:`urllib.request.OpenerDirector`). Normally we have been using
+confusingly named :class:`urllib.request.OpenerDirector`). Normally we have been using
the default opener - via ``urlopen`` - but you can create custom
openers. Openers use handlers. All the "heavy lifting" is done by the
handlers. Each handler knows how to open URLs for a particular URL scheme (http,
@@ -458,7 +451,7 @@ To illustrate creating and installing a handler we will use the
``HTTPBasicAuthHandler``. For a more detailed discussion of this subject --
including an explanation of how Basic Authentication works - see the `Basic
Authentication Tutorial
-`_.
+`__.
When authentication is required, the server sends a header (as well as the 401
error code) requesting authentication. This specifies the authentication scheme
diff --git a/Doc/includes/email-read-alternative.py b/Doc/includes/email-read-alternative.py
index 5ea84e62584a46..8d0b4e6eb6b6b5 100644
--- a/Doc/includes/email-read-alternative.py
+++ b/Doc/includes/email-read-alternative.py
@@ -8,8 +8,15 @@
from email import policy
from email.parser import BytesParser
-# An imaginary module that would make this work and be safe.
-from imaginary import magic_html_parser
+
+def magic_html_parser(html_text, partfiles):
+ """Return safety-sanitized html linked to partfiles.
+
+ Rewrite the href="cid:...." attributes to point to the filenames in partfiles.
+ Though not trivial, this should be possible using html.parser.
+ """
+ raise NotImplementedError("Add the magic needed")
+
# In a real program you'd get the filename from the arguments.
with open('outgoing.msg', 'rb') as fp:
@@ -62,9 +69,6 @@
print("Don't know how to display {}".format(richest.get_content_type()))
sys.exit()
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
- # The magic_html_parser has to rewrite the href="cid:...." attributes to
- # point to the filenames in partfiles. It also has to do a safety-sanitize
- # of the html. It could be written using html.parser.
f.write(magic_html_parser(body.get_content(), partfiles))
webbrowser.open(f.name)
os.remove(f.name)
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/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py
deleted file mode 100644
index 77daf8f16d227b..00000000000000
--- a/Doc/includes/sqlite3/adapter_point_1.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import sqlite3
-
-class Point:
- def __init__(self, x, y):
- self.x, self.y = x, y
-
- def __conform__(self, protocol):
- if protocol is sqlite3.PrepareProtocol:
- return "%f;%f" % (self.x, self.y)
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-
-p = Point(4.0, -3.2)
-cur.execute("select ?", (p,))
-print(cur.fetchone()[0])
-
-con.close()
diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py
deleted file mode 100644
index cb86331692b61d..00000000000000
--- a/Doc/includes/sqlite3/adapter_point_2.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sqlite3
-
-class Point:
- def __init__(self, x, y):
- self.x, self.y = x, y
-
-def adapt_point(point):
- return "%f;%f" % (point.x, point.y)
-
-sqlite3.register_adapter(Point, adapt_point)
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-
-p = Point(4.0, -3.2)
-cur.execute("select ?", (p,))
-print(cur.fetchone()[0])
-
-con.close()
diff --git a/Doc/includes/sqlite3/blob.py b/Doc/includes/sqlite3/blob.py
deleted file mode 100644
index ff58d6c352b652..00000000000000
--- a/Doc/includes/sqlite3/blob.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-con.execute("create table test(blob_col blob)")
-con.execute("insert into test(blob_col) values (zeroblob(13))")
-
-# Write to our blob, using two write operations:
-with con.blobopen("test", "blob_col", 1) as blob:
- blob.write(b"hello, ")
- blob.write(b"world.")
- # Modify the first and last bytes of our blob
- blob[0] = ord("H")
- blob[-1] = ord("!")
-
-# Read the contents of our blob
-with con.blobopen("test", "blob_col", 1) as blob:
- greeting = blob.read()
-
-print(greeting) # outputs "b'Hello, world!'"
diff --git a/Doc/includes/sqlite3/collation_reverse.py b/Doc/includes/sqlite3/collation_reverse.py
deleted file mode 100644
index 3504a350a04ecb..00000000000000
--- a/Doc/includes/sqlite3/collation_reverse.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import sqlite3
-
-def collate_reverse(string1, string2):
- if string1 == string2:
- return 0
- elif string1 < string2:
- return 1
- else:
- return -1
-
-con = sqlite3.connect(":memory:")
-con.create_collation("reverse", collate_reverse)
-
-cur = con.cursor()
-cur.execute("create table test(x)")
-cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
-cur.execute("select x from test order by x collate reverse")
-for row in cur:
- print(row)
-con.close()
diff --git a/Doc/includes/sqlite3/complete_statement.py b/Doc/includes/sqlite3/complete_statement.py
deleted file mode 100644
index a5c947969910d4..00000000000000
--- a/Doc/includes/sqlite3/complete_statement.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# A minimal SQLite shell for experiments
-
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-con.isolation_level = None
-cur = con.cursor()
-
-buffer = ""
-
-print("Enter your SQL commands to execute in sqlite3.")
-print("Enter a blank line to exit.")
-
-while True:
- line = input()
- if line == "":
- break
- buffer += line
- if sqlite3.complete_statement(buffer):
- try:
- buffer = buffer.strip()
- cur.execute(buffer)
-
- if buffer.lstrip().upper().startswith("SELECT"):
- print(cur.fetchall())
- except sqlite3.Error as e:
- err_msg = str(e)
- err_code = e.sqlite_errorcode
- err_name = e.sqlite_errorname
- print(f"{err_name} ({err_code}): {err_msg}")
- buffer = ""
-
-con.close()
diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py
deleted file mode 100644
index 5df828e3361246..00000000000000
--- a/Doc/includes/sqlite3/converter_point.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import sqlite3
-
-class Point:
- def __init__(self, x, y):
- self.x, self.y = x, y
-
- def __repr__(self):
- return "(%f;%f)" % (self.x, self.y)
-
-def adapt_point(point):
- return ("%f;%f" % (point.x, point.y)).encode('ascii')
-
-def convert_point(s):
- x, y = list(map(float, s.split(b";")))
- return Point(x, y)
-
-# Register the adapter
-sqlite3.register_adapter(Point, adapt_point)
-
-# Register the converter
-sqlite3.register_converter("point", convert_point)
-
-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.execute("insert into test(p) values (?)", (p,))
-cur.execute("select p from test")
-print("with declared types:", cur.fetchone()[0])
-cur.close()
-con.close()
-
-#######################
-# 1) Using column names
-con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
-cur = con.cursor()
-cur.execute("create table test(p)")
-
-cur.execute("insert into test(p) values (?)", (p,))
-cur.execute('select p as "p [point]" from test')
-print("with column names:", cur.fetchone()[0])
-cur.close()
-con.close()
diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py
deleted file mode 100644
index 2e1175ef44c641..00000000000000
--- a/Doc/includes/sqlite3/ctx_manager.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-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 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 lang(name) values (?)", ("Python",))
-except sqlite3.IntegrityError:
- 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
-con.close()
diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py
deleted file mode 100644
index ee0000e2b94a32..00000000000000
--- a/Doc/includes/sqlite3/execute_1.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-cur.execute("create table lang (name, first_appeared)")
-
-# This is the qmark style:
-cur.execute("insert into lang values (?, ?)", ("C", 1972))
-
-# The qmark style used with executemany():
-lang_list = [
- ("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 first_appeared=:year", {"year": 1972})
-print(cur.fetchall())
-
-con.close()
diff --git a/Doc/includes/sqlite3/executemany_1.py b/Doc/includes/sqlite3/executemany_1.py
deleted file mode 100644
index edf6f8b7ebe61a..00000000000000
--- a/Doc/includes/sqlite3/executemany_1.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import sqlite3
-
-class IterChars:
- def __init__(self):
- self.count = ord('a')
-
- def __iter__(self):
- return self
-
- def __next__(self):
- if self.count > ord('z'):
- raise StopIteration
- self.count += 1
- return (chr(self.count - 1),) # this is a 1-tuple
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-cur.execute("create table characters(c)")
-
-theIter = IterChars()
-cur.executemany("insert into characters(c) values (?)", theIter)
-
-cur.execute("select c from characters")
-print(cur.fetchall())
-
-con.close()
diff --git a/Doc/includes/sqlite3/executemany_2.py b/Doc/includes/sqlite3/executemany_2.py
deleted file mode 100644
index 02a594c861e15b..00000000000000
--- a/Doc/includes/sqlite3/executemany_2.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import sqlite3
-import string
-
-def char_generator():
- for c in string.ascii_lowercase:
- yield (c,)
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-cur.execute("create table characters(c)")
-
-cur.executemany("insert into characters(c) values (?)", char_generator())
-
-cur.execute("select c from characters")
-print(cur.fetchall())
-
-con.close()
diff --git a/Doc/includes/sqlite3/executescript.py b/Doc/includes/sqlite3/executescript.py
deleted file mode 100644
index aea8943fbee598..00000000000000
--- a/Doc/includes/sqlite3/executescript.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-cur.executescript("""
- create table person(
- firstname,
- lastname,
- age
- );
-
- create table book(
- title,
- author,
- published
- );
-
- insert into book(title, author, published)
- values (
- 'Dirk Gently''s Holistic Detective Agency',
- 'Douglas Adams',
- 1987
- );
- """)
-con.close()
diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py
deleted file mode 100644
index 624cfe262f38b3..00000000000000
--- a/Doc/includes/sqlite3/load_extension.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-
-# enable extension loading
-con.enable_load_extension(True)
-
-# Load the fulltext search extension
-con.execute("select load_extension('./fts3.so')")
-
-# alternatively you can load the extension using an API call:
-# con.load_extension("./fts3.so")
-
-# disable extension loading again
-con.enable_load_extension(False)
-
-# example from SQLite wiki
-con.execute("create virtual table recipe using fts3(name, ingredients)")
-con.executescript("""
- insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
- insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
- insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
- insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
- """)
-for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
- print(row)
-
-con.close()
diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py
deleted file mode 100644
index 16dc348bf001e2..00000000000000
--- a/Doc/includes/sqlite3/md5func.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import sqlite3
-import hashlib
-
-def md5sum(t):
- return hashlib.md5(t).hexdigest()
-
-con = sqlite3.connect(":memory:")
-con.create_function("md5", 1, md5sum)
-cur = con.cursor()
-cur.execute("select md5(?)", (b"foo",))
-print(cur.fetchone()[0])
-
-con.close()
diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py
deleted file mode 100644
index 11f96395b6c485..00000000000000
--- a/Doc/includes/sqlite3/mysumaggr.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import sqlite3
-
-class MySum:
- def __init__(self):
- self.count = 0
-
- def step(self, value):
- self.count += value
-
- def finalize(self):
- return self.count
-
-con = sqlite3.connect(":memory:")
-con.create_aggregate("mysum", 1, MySum)
-cur = con.cursor()
-cur.execute("create table test(i)")
-cur.execute("insert into test(i) values (1)")
-cur.execute("insert into test(i) values (2)")
-cur.execute("select mysum(i) from test")
-print(cur.fetchone()[0])
-
-con.close()
diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py
deleted file mode 100644
index 9de6e7b1b9052a..00000000000000
--- a/Doc/includes/sqlite3/row_factory.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import sqlite3
-
-def dict_factory(cursor, row):
- d = {}
- for idx, col in enumerate(cursor.description):
- d[col[0]] = row[idx]
- return d
-
-con = sqlite3.connect(":memory:")
-con.row_factory = dict_factory
-cur = con.cursor()
-cur.execute("select 1 as a")
-print(cur.fetchone()["a"])
-
-con.close()
diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py
deleted file mode 100644
index fc60287069a854..00000000000000
--- a/Doc/includes/sqlite3/rowclass.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-con.row_factory = sqlite3.Row
-
-cur = con.cursor()
-cur.execute("select 'John' as name, 42 as age")
-for row in cur:
- assert row[0] == row["name"]
- assert row["name"] == row["nAmE"]
- assert row[1] == row["age"]
- assert row[1] == row["AgE"]
-
-con.close()
diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py
deleted file mode 100644
index 48ea6fad15a898..00000000000000
--- a/Doc/includes/sqlite3/shortcut_methods.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import sqlite3
-
-langs = [
- ("C++", 1985),
- ("Objective-C", 1984),
-]
-
-con = sqlite3.connect(":memory:")
-
-# Create the table
-con.execute("create table lang(name, first_appeared)")
-
-# Fill the table
-con.executemany("insert into lang(name, first_appeared) values (?, ?)", langs)
-
-# Print the table contents
-for row in con.execute("select name, first_appeared from lang"):
- print(row)
-
-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
-con.close()
diff --git a/Doc/includes/sqlite3/sumintwindow.py b/Doc/includes/sqlite3/sumintwindow.py
deleted file mode 100644
index 0e915d6cc6ae68..00000000000000
--- a/Doc/includes/sqlite3/sumintwindow.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc
-import sqlite3
-
-
-class WindowSumInt:
- def __init__(self):
- self.count = 0
-
- def step(self, value):
- """Adds a row to the current window."""
- self.count += value
-
- def value(self):
- """Returns the current value of the aggregate."""
- return self.count
-
- def inverse(self, value):
- """Removes a row from the current window."""
- self.count -= value
-
- def finalize(self):
- """Returns the final value of the aggregate.
-
- Any clean-up actions should be placed here.
- """
- return self.count
-
-
-con = sqlite3.connect(":memory:")
-cur = con.execute("create table test(x, y)")
-values = [
- ("a", 4),
- ("b", 5),
- ("c", 3),
- ("d", 8),
- ("e", 1),
-]
-cur.executemany("insert into test values(?, ?)", values)
-con.create_window_function("sumint", 1, WindowSumInt)
-cur.execute("""
- select x, sumint(y) over (
- order by x rows between 1 preceding and 1 following
- ) as sum_y
- from test order by x
-""")
-print(cur.fetchall())
diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py
deleted file mode 100644
index c0d87cd559118c..00000000000000
--- a/Doc/includes/sqlite3/text_factory.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-
-AUSTRIA = "Österreich"
-
-# by default, rows are returned as str
-cur.execute("select ?", (AUSTRIA,))
-row = cur.fetchone()
-assert row[0] == AUSTRIA
-
-# but we can make sqlite3 always return bytestrings ...
-con.text_factory = bytes
-cur.execute("select ?", (AUSTRIA,))
-row = cur.fetchone()
-assert type(row[0]) is bytes
-# the bytestrings will be encoded in UTF-8, unless you stored garbage in the
-# database ...
-assert row[0] == AUSTRIA.encode("utf-8")
-
-# we can also implement a custom text_factory ...
-# here we implement one that appends "foo" to all strings
-con.text_factory = lambda x: x.decode("utf-8") + "foo"
-cur.execute("select ?", ("bar",))
-row = cur.fetchone()
-assert row[0] == "barfoo"
-
-con.close()
diff --git a/Doc/includes/tzinfo_examples.py b/Doc/includes/tzinfo_examples.py
index 9b9e32a553e7d8..1fa6e615e46a76 100644
--- a/Doc/includes/tzinfo_examples.py
+++ b/Doc/includes/tzinfo_examples.py
@@ -71,7 +71,7 @@ def first_sunday_on_or_after(dt):
# DST start and end times. For a complete and up-to-date set of DST rules
# and timezone definitions, visit the Olson Database (or try pytz):
# http://www.twinsun.com/tz/tz-link.htm
-# http://sourceforge.net/projects/pytz/ (might not be up-to-date)
+# https://sourceforge.net/projects/pytz/ (might not be up-to-date)
#
# In the US, since 2007, DST starts at 2am (standard time) on the second
# Sunday in March, which is the first Sunday on or after Mar 8.
diff --git a/Doc/includes/wasm-notavail.rst b/Doc/includes/wasm-notavail.rst
new file mode 100644
index 00000000000000..e680e1f9b43807
--- /dev/null
+++ b/Doc/includes/wasm-notavail.rst
@@ -0,0 +1,7 @@
+.. include for modules that don't work on WASM
+
+.. availability:: not Emscripten, not WASI.
+
+ This module does not work or is not available on WebAssembly platforms
+ ``wasm32-emscripten`` and ``wasm32-wasi``. See
+ :ref:`wasm-availability` for more information.
diff --git a/Doc/install/index.rst b/Doc/install/index.rst
index 7f7be117009887..d2d8e567c03c2b 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -65,7 +65,7 @@ If you download a module source distribution, you can tell pretty quickly if it
was packaged and distributed in the standard way, i.e. using the Distutils.
First, the distribution's name and version number will be featured prominently
in the name of the downloaded archive, e.g. :file:`foo-1.0.tar.gz` or
-:file:`widget-0.9.7.zip`. Next, the archive will unpack into a similarly-named
+:file:`widget-0.9.7.zip`. Next, the archive will unpack into a similarly named
directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the
distribution will contain a setup script :file:`setup.py`, and a file named
:file:`README.txt` or possibly just :file:`README`, which should explain that
@@ -761,7 +761,7 @@ And on Windows, the configuration files are:
+--------------+-------------------------------------------------+-------+
On all platforms, the "personal" file can be temporarily disabled by
-passing the `--no-user-cfg` option.
+passing the ``--no-user-cfg`` option.
Notes:
@@ -1062,7 +1062,7 @@ normal libraries do.
.. seealso::
- `Building Python modules on MS Windows platform with MinGW `_
+ `Building Python modules on MS Windows platform with MinGW `_
Information about building the required libraries for the MinGW environment.
diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst
index 4bacc7ba0c2cf2..e158bf1c4c0c7f 100644
--- a/Doc/installing/index.rst
+++ b/Doc/installing/index.rst
@@ -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
diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst
index fce02e28009330..d85ad94e9b7fe4 100644
--- a/Doc/library/2to3.rst
+++ b/Doc/library/2to3.rst
@@ -1,7 +1,7 @@
.. _2to3-reference:
-2to3 - Automated Python 2 to 3 code translation
-===============================================
+2to3 --- Automated Python 2 to 3 code translation
+=================================================
.. sectionauthor:: Benjamin Peterson
@@ -456,8 +456,8 @@ and off individually. They are described here in more detail.
``from future_builtins import zip`` appears.
-:mod:`lib2to3` - 2to3's library
--------------------------------
+:mod:`lib2to3` --- 2to3's library
+---------------------------------
.. module:: lib2to3
:synopsis: The 2to3 library
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 d0a65e76b84237..363596782d8e3e 100644
--- a/Doc/library/__main__.rst
+++ b/Doc/library/__main__.rst
@@ -124,7 +124,7 @@ 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___ ==
+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::
@@ -259,7 +259,7 @@ one mentioned below are preferred.
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]``.
+ block. You can invoke it with ``python -m venv [directory]``.
See :mod:`runpy` for more details on the :option:`-m` flag to the
interpreter executable.
diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst
index 1e6452b7b826fd..3d7e354d1e368d 100644
--- a/Doc/library/_thread.rst
+++ b/Doc/library/_thread.rst
@@ -140,7 +140,9 @@ This module defines the following constants and functions:
information (4 KiB pages are common; using multiples of 4096 for the stack size is
the suggested approach in the absence of more specific information).
- .. availability:: Windows, systems with POSIX threads.
+ .. availability:: Windows, pthreads.
+
+ Unix platforms with POSIX threads support.
.. data:: TIMEOUT_MAX
@@ -155,21 +157,21 @@ This module defines the following constants and functions:
Lock objects have the following methods:
-.. method:: lock.acquire(waitflag=1, timeout=-1)
+.. method:: lock.acquire(blocking=True, timeout=-1)
Without any optional argument, this method acquires the lock unconditionally, if
necessary waiting until it is released by another thread (only one thread at a
time can acquire a lock --- that's their reason for existence).
- If the integer *waitflag* argument is present, the action depends on its
- value: if it is zero, the lock is only acquired if it can be acquired
- immediately without waiting, while if it is nonzero, the lock is acquired
+ If the *blocking* argument is present, the action depends on its
+ value: if it is False, the lock is only acquired if it can be acquired
+ immediately without waiting, while if it is True, the lock is acquired
unconditionally as above.
If the floating-point *timeout* argument is present and positive, it
specifies the maximum wait time in seconds before returning. A negative
*timeout* argument specifies an unbounded wait. You cannot specify
- a *timeout* if *waitflag* is zero.
+ a *timeout* if *blocking* is False.
The return value is ``True`` if the lock is acquired successfully,
``False`` if not.
@@ -204,7 +206,7 @@ In addition to these methods, lock objects can also be used via the
**Caveats:**
- .. index:: module: signal
+ .. index:: pair: module; signal
* Threads interact strangely with interrupts: the :exc:`KeyboardInterrupt`
exception will be received by an arbitrary thread. (When the :mod:`signal`
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index 3b74622e7ff46c..274b2d69f0ab5c 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -21,7 +21,7 @@ The :mod:`collections` module has some concrete classes that derive from
ABCs; these can, of course, be further derived. In addition, the
:mod:`collections.abc` submodule has some ABCs that can be used to test whether
a class or instance provides a particular interface, for example, if it is
-hashable or if it is a mapping.
+:term:`hashable` or if it is a mapping.
This module provides the metaclass :class:`ABCMeta` for defining ABCs and
diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst
index edb4bf86e5a0aa..9f20a30193fa70 100644
--- a/Doc/library/aifc.rst
+++ b/Doc/library/aifc.rst
@@ -13,8 +13,9 @@
single: AIFF-C
-.. deprecated:: 3.11
- The :mod:`aifc` module is deprecated (see :pep:`594` for details).
+.. deprecated-removed:: 3.11 3.13
+ The :mod:`aifc` module is deprecated
+ (see :pep:`PEP 594 <594#aifc>` for details).
--------------
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index b5a2b794c2385f..19c510fccf050c 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -34,9 +34,9 @@ around an instance of :class:`argparse.ArgumentParser`. It is a container for
argument specifications and has options that apply the parser as whole::
parser = argparse.ArgumentParser(
- prog = 'ProgramName',
- description = 'What the program does',
- epilog = 'Text at the bottom of help')
+ prog='ProgramName',
+ description='What the program does',
+ epilog='Text at the bottom of help')
The :meth:`ArgumentParser.add_argument` method attaches individual argument
specifications to the parser. It supports positional arguments, options that
@@ -63,11 +63,11 @@ Name Description
action_ Specify how an argument should be handled ``'store'``, ``'store_const'``, ``'store_true'``, ``'append'``, ``'append_const'``, ``'count'``, ``'help'``, ``'version'``
choices_ Limit values to a specific set of choices ``['foo', 'bar']``, ``range(1, 10)``, or :class:`~collections.abc.Container` instance
const_ Store a constant value
-default_ Default value used when an argument is not provided Defaults to *None*
+default_ Default value used when an argument is not provided Defaults to ``None``
dest_ Specify the attribute name used in the result namespace
help_ Help message for an argument
metavar_ Alternate display name for the argument as shown in help
-nargs_ Number of times the argument can be used :class:`int`, ``'?'``, ``'*'``, ``'+'``, or ``argparse.REMAINDER``
+nargs_ Number of times the argument can be used :class:`int`, ``'?'``, ``'*'``, or ``'+'``
required_ Indicate whether an argument is required or optional ``True`` or ``False``
type_ Automatically convert an argument to the given type :class:`int`, :class:`float`, ``argparse.FileType('w')``, or callable function
====================== =========================================================== ==========================================================================================================================
@@ -201,9 +201,10 @@ ArgumentParser objects
* usage_ - The string describing the program usage (default: generated from
arguments added to parser)
- * description_ - Text to display before the argument help (default: none)
+ * description_ - Text to display before the argument help
+ (by default, no text)
- * epilog_ - Text to display after the argument help (default: none)
+ * epilog_ - Text to display after the argument help (by default, no text)
* parents_ - A list of :class:`ArgumentParser` objects whose arguments should
also be included
@@ -555,7 +556,7 @@ disallowed.
fromfile_prefix_chars
^^^^^^^^^^^^^^^^^^^^^
-Sometimes, when dealing with a particularly long argument lists, it
+Sometimes, 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
@@ -754,7 +755,7 @@ The add_argument() method
* type_ - The type to which the command-line argument should be converted.
- * choices_ - A container of the allowable values for the argument.
+ * choices_ - A sequence of the allowable values for the argument.
* required_ - Whether or not the command-line option may be omitted
(optionals only).
@@ -1180,7 +1181,7 @@ 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. A
:exc:`~json.JSONDecodeError` would not be well formatted and a
-:exc:`FileNotFound` exception would not be handled at all.
+:exc:`FileNotFoundError` exception would not be handled at all.
Even :class:`~argparse.FileType` has its limitations for use with the ``type``
keyword. If one argument uses *FileType* and then a subsequent argument fails,
@@ -1198,7 +1199,7 @@ choices
^^^^^^^
Some command-line arguments should be selected from a restricted set of values.
-These can be handled by passing a container object as the *choices* keyword
+These can be handled by passing a sequence object as the *choices* keyword
argument to :meth:`~ArgumentParser.add_argument`. When the command line is
parsed, argument values will be checked, and an error message will be displayed
if the argument was not one of the acceptable values::
@@ -1212,9 +1213,9 @@ if the argument was not one of the acceptable values::
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
'paper', 'scissors')
-Note that inclusion in the *choices* container is checked after any type_
+Note that inclusion in the *choices* sequence is checked after any type_
conversions have been performed, so the type of the objects in the *choices*
-container should match the type_ specified::
+sequence should match the type_ specified::
>>> parser = argparse.ArgumentParser(prog='doors.py')
>>> parser.add_argument('door', type=int, choices=range(1, 4))
@@ -1224,8 +1225,8 @@ container should match the type_ specified::
usage: doors.py [-h] {1,2,3}
doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3)
-Any container can be passed as the *choices* value, so :class:`list` objects,
-:class:`set` objects, and custom containers are all supported.
+Any sequence can be passed as the *choices* value, so :class:`list` objects,
+:class:`tuple` objects, and custom sequences are all supported.
Use of :class:`enum.Enum` is not recommended because it is difficult to
control its appearance in usage, help, and error messages.
@@ -1434,7 +1435,7 @@ Action classes
Action classes implement the Action API, a callable which returns a callable
which processes arguments from the command-line. Any object which follows
this API may be passed as the ``action`` parameter to
-:meth:`add_argument`.
+:meth:`~ArgumentParser.add_argument`.
.. class:: Action(option_strings, dest, nargs=None, const=None, default=None, \
type=None, choices=None, required=False, help=None, \
@@ -1698,7 +1699,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,
@@ -1709,7 +1710,7 @@ Sub-commands
:class:`ArgumentParser` supports the creation of such sub-commands with the
:meth:`add_subparsers` method. The :meth:`add_subparsers` method is normally
called with no arguments and returns a special action object. This object
- has a single method, :meth:`~ArgumentParser.add_parser`, which takes a
+ has a single method, :meth:`~_SubParsersAction.add_parser`, which takes a
command name and any :class:`ArgumentParser` constructor arguments, and
returns an :class:`ArgumentParser` object that can be modified as usual.
@@ -1775,7 +1776,7 @@ Sub-commands
for that particular parser will be printed. The help message will not
include parent parser or sibling parser messages. (A help message for each
subparser command, however, can be given by supplying the ``help=`` argument
- to :meth:`add_parser` as above.)
+ to :meth:`~_SubParsersAction.add_parser` as above.)
::
@@ -1853,7 +1854,7 @@ Sub-commands
...
>>> # create the top-level parser
>>> parser = argparse.ArgumentParser()
- >>> subparsers = parser.add_subparsers()
+ >>> subparsers = parser.add_subparsers(required=True)
>>>
>>> # create the parser for the "foo" command
>>> parser_foo = subparsers.add_parser('foo')
@@ -1914,8 +1915,8 @@ FileType objects
Namespace(out=<_io.TextIOWrapper name='file.txt' mode='w' encoding='UTF-8'>, raw=<_io.FileIO name='raw.dat' mode='wb'>)
FileType objects understand the pseudo-argument ``'-'`` and automatically
- convert this into ``sys.stdin`` for readable :class:`FileType` objects and
- ``sys.stdout`` for writable :class:`FileType` objects::
+ convert this into :data:`sys.stdin` for readable :class:`FileType` objects and
+ :data:`sys.stdout` for writable :class:`FileType` objects::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
@@ -1932,7 +1933,7 @@ Argument groups
.. method:: ArgumentParser.add_argument_group(title=None, description=None)
By default, :class:`ArgumentParser` groups command-line arguments into
- "positional arguments" and "optional arguments" when displaying help
+ "positional arguments" and "options" when displaying help
messages. When there is a better conceptual grouping of arguments than this
default one, appropriate groups can be created using the
:meth:`add_argument_group` method::
@@ -2124,7 +2125,7 @@ the populated namespace and the list of remaining argument strings.
.. warning::
:ref:`Prefix matching ` rules apply to
- :meth:`parse_known_args`. The parser may consume an option even if it's just
+ :meth:`~ArgumentParser.parse_known_args`. The parser may consume an option even if it's just
a prefix of one of its known options, instead of leaving it in the remaining
arguments list.
@@ -2185,7 +2186,7 @@ support this parsing style.
These parsers do not support all the argparse features, and will raise
exceptions if unsupported features are used. In particular, subparsers,
-``argparse.REMAINDER``, and mutually exclusive groups that include both
+and mutually exclusive groups that include both
optionals and positionals are not supported.
The following example shows the difference between
@@ -2262,3 +2263,17 @@ A partial upgrade path from :mod:`optparse` to :mod:`argparse`:
* Replace the OptionParser constructor ``version`` argument with a call to
``parser.add_argument('--version', action='version', version='')``.
+
+Exceptions
+----------
+
+.. exception:: ArgumentError
+
+ An error from creating or using an argument (optional or positional).
+
+ The string value of this exception is the message, augmented with
+ information about the argument that caused it.
+
+.. exception:: ArgumentTypeError
+
+ Raised when something goes wrong converting a command line string to a type.
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index c7f137d15b4b86..75c49e0f6d1ebe 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
@@ -60,7 +60,15 @@ Notes:
The actual representation of values is determined by the machine architecture
(strictly speaking, by the C implementation). The actual size can be accessed
-through the :attr:`itemsize` attribute.
+through the :attr:`array.itemsize` attribute.
+
+The module defines the following item:
+
+
+.. data:: typecodes
+
+ A string with all available type codes.
+
The module defines the following type:
@@ -77,164 +85,160 @@ The module defines the following type:
to add initial items to the array. Otherwise, the iterable initializer is
passed to the :meth:`extend` method.
- .. audit-event:: array.__new__ typecode,initializer array.array
-
-.. data:: typecodes
+ Array objects support the ordinary sequence operations of indexing, slicing,
+ concatenation, and multiplication. When using slice assignment, the assigned
+ value must be an array object with the same type code; in all other cases,
+ :exc:`TypeError` is raised. Array objects also implement the buffer interface,
+ and may be used wherever :term:`bytes-like objects ` are supported.
- A string with all available type codes.
+ .. audit-event:: array.__new__ typecode,initializer array.array
-Array objects support the ordinary sequence operations of indexing, slicing,
-concatenation, and multiplication. When using slice assignment, the assigned
-value must be an array object with the same type code; in all other cases,
-:exc:`TypeError` is raised. Array objects also implement the buffer interface,
-and may be used wherever :term:`bytes-like objects ` are supported.
-The following data items and methods are also supported:
+ .. attribute:: typecode
-.. attribute:: array.typecode
+ The typecode character used to create the array.
- The typecode character used to create the array.
+ .. attribute:: itemsize
-.. attribute:: array.itemsize
+ The length in bytes of one array item in the internal representation.
- The length in bytes of one array item in the internal representation.
+ .. method:: append(x)
-.. method:: array.append(x)
+ Append a new item with value *x* to the end of the array.
- Append a new item with value *x* to the end of the array.
+ .. method:: buffer_info()
-.. method:: array.buffer_info()
+ Return a tuple ``(address, length)`` giving the current memory address and the
+ length in elements of the buffer used to hold array's contents. The size of the
+ memory buffer in bytes can be computed as ``array.buffer_info()[1] *
+ array.itemsize``. This is occasionally useful when working with low-level (and
+ inherently unsafe) I/O interfaces that require memory addresses, such as certain
+ :c:func:`!ioctl` operations. The returned numbers are valid as long as the array
+ exists and no length-changing operations are applied to it.
- Return a tuple ``(address, length)`` giving the current memory address and the
- length in elements of the buffer used to hold array's contents. The size of the
- memory buffer in bytes can be computed as ``array.buffer_info()[1] *
- array.itemsize``. This is occasionally useful when working with low-level (and
- inherently unsafe) I/O interfaces that require memory addresses, such as certain
- :c:func:`ioctl` operations. The returned numbers are valid as long as the array
- exists and no length-changing operations are applied to it.
+ .. note::
- .. note::
+ When using array objects from code written in C or C++ (the only way to
+ effectively make use of this information), it makes more sense to use the buffer
+ interface supported by array objects. This method is maintained for backward
+ compatibility and should be avoided in new code. The buffer interface is
+ documented in :ref:`bufferobjects`.
- When using array objects from code written in C or C++ (the only way to
- effectively make use of this information), it makes more sense to use the buffer
- interface supported by array objects. This method is maintained for backward
- compatibility and should be avoided in new code. The buffer interface is
- documented in :ref:`bufferobjects`.
+ .. method:: byteswap()
-.. method:: array.byteswap()
+ "Byteswap" all items of the array. This is only supported for values which are
+ 1, 2, 4, or 8 bytes in size; for other types of values, :exc:`RuntimeError` is
+ raised. It is useful when reading data from a file written on a machine with a
+ different byte order.
- "Byteswap" all items of the array. This is only supported for values which are
- 1, 2, 4, or 8 bytes in size; for other types of values, :exc:`RuntimeError` is
- raised. It is useful when reading data from a file written on a machine with a
- different byte order.
+ .. method:: count(x)
-.. method:: array.count(x)
+ Return the number of occurrences of *x* in the array.
- Return the number of occurrences of *x* in the array.
+ .. method:: extend(iterable)
-.. method:: array.extend(iterable)
+ Append items from *iterable* to the end of the array. If *iterable* is another
+ array, it must have *exactly* the same type code; if not, :exc:`TypeError` will
+ be raised. If *iterable* is not an array, it must be iterable and its elements
+ must be the right type to be appended to the array.
- Append items from *iterable* to the end of the array. If *iterable* is another
- array, it must have *exactly* the same type code; if not, :exc:`TypeError` will
- be raised. If *iterable* is not an array, it must be iterable and its elements
- must be the right type to be appended to the array.
+ .. method:: frombytes(s)
-.. method:: array.frombytes(s)
+ Appends items from the string, interpreting the string as an array of machine
+ values (as if it had been read from a file using the :meth:`fromfile` method).
- Appends items from the string, interpreting the string as an array of machine
- values (as if it had been read from a file using the :meth:`fromfile` method).
+ .. versionadded:: 3.2
+ :meth:`!fromstring` is renamed to :meth:`frombytes` for clarity.
- .. versionadded:: 3.2
- :meth:`fromstring` is renamed to :meth:`frombytes` for clarity.
+ .. method:: fromfile(f, n)
-.. method:: array.fromfile(f, n)
+ Read *n* items (as machine values) from the :term:`file object` *f* and append
+ them to the end of the array. If less than *n* items are available,
+ :exc:`EOFError` is raised, but the items that were available are still
+ inserted into the array.
- Read *n* items (as machine values) from the :term:`file object` *f* and append
- them to the end of the array. If less than *n* items are available,
- :exc:`EOFError` is raised, but the items that were available are still
- inserted into the array.
+ .. method:: fromlist(list)
-.. method:: array.fromlist(list)
+ Append items from the list. This is equivalent to ``for x in list:
+ a.append(x)`` except that if there is a type error, the array is unchanged.
- Append items from the list. This is equivalent to ``for x in list:
- a.append(x)`` except that if there is a type error, the array is unchanged.
+ .. method:: fromunicode(s)
-.. method:: array.fromunicode(s)
+ Extends this array with data from the given unicode string. The array must
+ be a type ``'u'`` array; otherwise a :exc:`ValueError` is raised. Use
+ ``array.frombytes(unicodestring.encode(enc))`` to append Unicode data to an
+ array of some other type.
- Extends this array with data from the given unicode string. The array must
- be a type ``'u'`` array; otherwise a :exc:`ValueError` is raised. Use
- ``array.frombytes(unicodestring.encode(enc))`` to append Unicode data to an
- array of some other type.
+ .. method:: index(x[, start[, stop]])
-.. method:: array.index(x[, start[, stop]])
+ Return the smallest *i* such that *i* is the index of the first occurrence of
+ *x* in the array. The optional arguments *start* and *stop* can be
+ specified to search for *x* within a subsection of the array. Raise
+ :exc:`ValueError` if *x* is not found.
- Return the smallest *i* such that *i* is the index of the first occurrence of
- *x* in the array. The optional arguments *start* and *stop* can be
- specified to search for *x* within a subsection of the array. Raise
- :exc:`ValueError` if *x* is not found.
+ .. versionchanged:: 3.10
+ Added optional *start* and *stop* parameters.
- .. versionchanged:: 3.10
- Added optional *start* and *stop* parameters.
-.. method:: array.insert(i, x)
+ .. method:: insert(i, x)
- Insert a new item with value *x* in the array before position *i*. Negative
- values are treated as being relative to the end of the array.
+ Insert a new item with value *x* in the array before position *i*. Negative
+ values are treated as being relative to the end of the array.
-.. method:: array.pop([i])
+ .. method:: pop([i])
- Removes the item with the index *i* from the array and returns it. The optional
- argument defaults to ``-1``, so that by default the last item is removed and
- returned.
+ Removes the item with the index *i* from the array and returns it. The optional
+ argument defaults to ``-1``, so that by default the last item is removed and
+ returned.
-.. method:: array.remove(x)
+ .. method:: remove(x)
- Remove the first occurrence of *x* from the array.
+ Remove the first occurrence of *x* from the array.
-.. method:: array.reverse()
+ .. method:: reverse()
- Reverse the order of the items in the array.
+ Reverse the order of the items in the array.
-.. method:: array.tobytes()
+ .. method:: tobytes()
- Convert the array to an array of machine values and return the bytes
- representation (the same sequence of bytes that would be written to a file by
- the :meth:`tofile` method.)
+ Convert the array to an array of machine values and return the bytes
+ representation (the same sequence of bytes that would be written to a file by
+ the :meth:`tofile` method.)
- .. versionadded:: 3.2
- :meth:`tostring` is renamed to :meth:`tobytes` for clarity.
+ .. versionadded:: 3.2
+ :meth:`!tostring` is renamed to :meth:`tobytes` for clarity.
-.. method:: array.tofile(f)
+ .. method:: tofile(f)
- Write all items (as machine values) to the :term:`file object` *f*.
+ Write all items (as machine values) to the :term:`file object` *f*.
-.. method:: array.tolist()
+ .. method:: tolist()
- Convert the array to an ordinary list with the same items.
+ Convert the array to an ordinary list with the same items.
-.. method:: array.tounicode()
+ .. method:: tounicode()
- Convert the array to a unicode string. The array must be a type ``'u'`` array;
- otherwise a :exc:`ValueError` is raised. Use ``array.tobytes().decode(enc)`` to
- obtain a unicode string from an array of some other type.
+ Convert the array to a unicode string. The array must be a type ``'u'`` array;
+ otherwise a :exc:`ValueError` is raised. Use ``array.tobytes().decode(enc)`` to
+ obtain a unicode string from an array of some other type.
When an array object is printed or converted to a string, it is represented as
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index b10aa7cd50d173..c92826621ff558 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -45,7 +45,7 @@ Node classes
This is the base of all AST node classes. The actual node classes are
derived from the :file:`Parser/Python.asdl` file, which is reproduced
- :ref:`below `. They are defined in the :mod:`_ast` C
+ :ref:`above `. They are defined in the :mod:`_ast` C
module and re-exported in :mod:`ast`.
There is one class defined for each left-hand side symbol in the abstract
@@ -481,7 +481,7 @@ Expressions
Comparison operator tokens.
-.. class:: Call(func, args, keywords, starargs, kwargs)
+.. class:: Call(func, args, keywords)
A function call. ``func`` is the function, which will often be a
:class:`Name` or :class:`Attribute` object. Of the arguments:
@@ -491,7 +491,7 @@ Expressions
arguments passed by keyword.
When creating a ``Call`` node, ``args`` and ``keywords`` are required, but
- they can be empty lists. ``starargs`` and ``kwargs`` are optional.
+ they can be empty lists.
.. doctest::
@@ -1818,7 +1818,7 @@ Function and class definitions
type_ignores=[])
-.. class:: ClassDef(name, bases, keywords, starargs, kwargs, body, decorator_list)
+.. class:: ClassDef(name, bases, keywords, body, decorator_list)
A class definition.
@@ -1827,9 +1827,6 @@ Function and class definitions
* ``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.
* ``body`` is a list of nodes representing the code within the class
definition.
* ``decorator_list`` is a list of nodes, as in :class:`FunctionDef`.
@@ -1950,7 +1947,7 @@ and classes for traversing abstract syntax trees:
If source contains a null character ('\0'), :exc:`ValueError` is raised.
- .. warning::
+ .. 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`
@@ -1990,20 +1987,28 @@ and classes for traversing abstract syntax trees:
.. function:: literal_eval(node_or_string)
- Safely evaluate an expression node or a string containing a Python literal or
+ Evaluate an expression node or a string containing only a Python literal or
container display. The string or node provided may only consist of the
following Python literal structures: strings, bytes, numbers, tuples, lists,
dicts, sets, booleans, ``None`` and ``Ellipsis``.
- This can be used for safely evaluating strings containing Python values from
- untrusted sources without the need to parse the values oneself. It is not
- capable of evaluating arbitrarily complex expressions, for example involving
- operators or indexing.
+ This can be used for evaluating strings containing Python values without the
+ need to parse the values oneself. It is not capable of evaluating
+ arbitrarily complex expressions, for example involving operators or
+ indexing.
+
+ This function had been documented as "safe" in the past without defining
+ what that meant. That was misleading. This is specifically designed not to
+ execute Python code, unlike the more general :func:`eval`. There is no
+ namespace, no name lookups, or ability to call out. But it is not free from
+ attack: A relatively small input can lead to memory exhaustion or to C stack
+ exhaustion, crashing the process. There is also the possibility for
+ excessive CPU consumption denial of service on some inputs. Calling it on
+ untrusted data is thus not recommended.
.. warning::
- It is possible to crash the Python interpreter with a
- sufficiently large/complex string due to stack depth limitations
- in Python's AST compiler.
+ It is possible to crash the Python interpreter due to stack depth
+ limitations in Python's AST compiler.
It can raise :exc:`ValueError`, :exc:`TypeError`, :exc:`SyntaxError`,
:exc:`MemoryError` and :exc:`RecursionError` depending on the malformed
@@ -2268,7 +2273,7 @@ to stdout. Otherwise, the content is read from stdin.
code that generated them. This is helpful for tools that make source code
transformations.
- `leoAst.py `_ unifies the
+ `leoAst.py `_ unifies the
token-based and parse-tree-based views of python programs by inserting
two-way links between tokens and ast nodes.
diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst
index 4354444a1d3314..32e04ad6d19533 100644
--- a/Doc/library/asynchat.rst
+++ b/Doc/library/asynchat.rst
@@ -10,8 +10,9 @@
**Source code:** :source:`Lib/asynchat.py`
-.. deprecated:: 3.6
- :mod:`asynchat` will be removed in Python 3.12 (:pep:`594`).
+.. deprecated-removed:: 3.6 3.12
+ The :mod:`asynchat` module is deprecated
+ (see :pep:`PEP 594 <594#asynchat>` for details).
Please use :mod:`asyncio` instead.
--------------
@@ -33,6 +34,7 @@ Typically an :class:`asyncore.dispatcher` server channel generates new
:class:`asynchat.async_chat` channel objects as it receives incoming
connection requests.
+.. include:: ../includes/wasm-notavail.rst
.. class:: async_chat()
@@ -124,7 +126,7 @@ connection requests.
.. method:: async_chat.push_with_producer(producer)
Takes a producer object and adds it to the producer queue associated with
- the channel. When all currently-pushed producers have been exhausted the
+ the channel. When all currently pushed producers have been exhausted the
channel will consume this producer's data by calling its :meth:`more`
method and send the data to the remote endpoint.
diff --git a/Doc/library/asyncio-api-index.rst b/Doc/library/asyncio-api-index.rst
index a4e38e469d82f0..ad475150fe7d91 100644
--- a/Doc/library/asyncio-api-index.rst
+++ b/Doc/library/asyncio-api-index.rst
@@ -21,8 +21,25 @@ await on multiple things with timeouts.
* - :func:`run`
- Create event loop, run a coroutine, close the loop.
+ * - :class:`Runner`
+ - A context manager that simplifies multiple async function calls.
+
+ * - :class:`Task`
+ - Task object.
+
+ * - :class:`TaskGroup`
+ - A context manager that holds a group of tasks. Provides
+ a convenient and reliable way to wait for all tasks in the group to
+ finish.
+
* - :func:`create_task`
- - Start an asyncio Task.
+ - Start an asyncio Task, then returns it.
+
+ * - :func:`current_task`
+ - Return the current Task.
+
+ * - :func:`all_tasks`
+ - Return all tasks that are not yet finished for an event loop.
* - ``await`` :func:`sleep`
- Sleep for a number of seconds.
@@ -39,14 +56,8 @@ await on multiple things with timeouts.
* - ``await`` :func:`wait`
- Monitor for completion.
- * - :func:`current_task`
- - Return the current Task.
-
- * - :func:`all_tasks`
- - Return all tasks for an event loop.
-
- * - :class:`Task`
- - Task object.
+ * - :func:`timeout`
+ - Run with a timeout. Useful in cases when ``wait_for`` is not suitable.
* - :func:`to_thread`
- Asynchronously run a function in a separate OS thread.
diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst
index 77f1128de50c95..921a394a59fec7 100644
--- a/Doc/library/asyncio-dev.rst
+++ b/Doc/library/asyncio-dev.rst
@@ -109,7 +109,7 @@ that the event loop runs in.
There is currently no way to schedule coroutines or callbacks directly
from a different process (such as one started with
-:mod:`multiprocessing`). The :ref:`Event Loop Methods `
+:mod:`multiprocessing`). The :ref:`asyncio-event-loop-methods`
section lists APIs that can read from pipes and watch file descriptors
without blocking the event loop. In addition, asyncio's
:ref:`Subprocess ` APIs provide a way to start a
@@ -148,6 +148,11 @@ adjusted::
logging.getLogger("asyncio").setLevel(logging.WARNING)
+Network logging can block the event loop. It is recommended to use
+a separate thread for handling logs or use non-blocking IO. For example,
+see :ref:`blocking-handlers`.
+
+
.. _asyncio-coroutine-not-scheduled:
Detect never-awaited coroutines
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 4f0f8c06fee787..3644c17c6b37c4 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -1,6 +1,8 @@
.. currentmodule:: asyncio
+.. _asyncio-event-loop:
+
==========
Event Loop
==========
@@ -31,7 +33,8 @@ an event loop:
Return the running event loop in the current OS thread.
- If there is no running event loop a :exc:`RuntimeError` is raised.
+ Raise a :exc:`RuntimeError` if there is no running event loop.
+
This function can only be called from a coroutine or a callback.
.. versionadded:: 3.7
@@ -40,27 +43,35 @@ an event loop:
Get the current event loop.
- If there is no current event loop set in the current OS thread,
- the OS thread is main, and :func:`set_event_loop` has not yet
- been called, asyncio will create a new event loop and set it as the
- current one.
+ When called from a coroutine or a callback (e.g. scheduled with
+ call_soon or similar API), this function will always return the
+ running event loop.
+
+ If there is no running event loop set, the function will return
+ the result of the ``get_event_loop_policy().get_event_loop()`` call.
Because this function has rather complex behavior (especially
when custom event loop policies are in use), using the
:func:`get_running_loop` function is preferred to :func:`get_event_loop`
in coroutines and callbacks.
- Consider also using the :func:`asyncio.run` function instead of using
- lower level functions to manually create and close an event loop.
+ As noted above, consider using the higher-level :func:`asyncio.run` function,
+ instead of using these lower level functions to manually create and close an
+ event loop.
- .. deprecated:: 3.10
- Deprecation warning is emitted if there is no running event loop.
- In future Python releases, this function will be an alias of
- :func:`get_running_loop`.
+ .. note::
+ In Python versions 3.10.0--3.10.8 and 3.11.0 this function
+ (and other functions which use it implicitly) emitted a
+ :exc:`DeprecationWarning` if there was no running event loop, even if
+ the current loop was set on the policy.
+ In Python versions 3.10.9, 3.11.1 and 3.12 they emit a
+ :exc:`DeprecationWarning` if there is no running event loop and no
+ current loop is set.
+ In some future Python release this will become an error.
.. function:: set_event_loop(loop)
- Set *loop* as a current event loop for the current OS thread.
+ Set *loop* as the current event loop for the current OS thread.
.. function:: new_event_loop()
@@ -92,7 +103,7 @@ This documentation page contains the following sections:
loop APIs.
-.. _asyncio-event-loop:
+.. _asyncio-event-loop-methods:
Event Loop Methods
==================
@@ -181,12 +192,15 @@ Running and stopping the loop
.. coroutinemethod:: loop.shutdown_default_executor()
Schedule the closure of the default executor and wait for it to join all of
- the threads in the :class:`ThreadPoolExecutor`. After calling this method, a
- :exc:`RuntimeError` will be raised if :meth:`loop.run_in_executor` is called
- while using the default executor.
+ the threads in the :class:`~concurrent.futures.ThreadPoolExecutor`.
+ Once this method has been called,
+ using the default executor with :meth:`loop.run_in_executor`
+ will raise a :exc:`RuntimeError`.
- Note that there is no need to call this function when
- :func:`asyncio.run` is used.
+ .. note::
+
+ Do not call this method when using :func:`asyncio.run`,
+ as the latter handles default executor shutdown automatically.
.. versionadded:: 3.9
@@ -199,22 +213,23 @@ Scheduling callbacks
Schedule the *callback* :term:`callback` to be called with
*args* arguments at the next iteration of the event loop.
+ Return an instance of :class:`asyncio.Handle`,
+ which can be used later to cancel the callback.
+
Callbacks are called in the order in which they are registered.
Each callback will be called exactly once.
- An optional keyword-only *context* argument allows specifying a
+ The optional keyword-only *context* argument specifies a
custom :class:`contextvars.Context` for the *callback* to run in.
- The current context is used when no *context* is provided.
+ Callbacks use the current context when no *context* is provided.
- An instance of :class:`asyncio.Handle` is returned, which can be
- used later to cancel the callback.
-
- This method is not thread-safe.
+ Unlike :meth:`call_soon_threadsafe`, this method is not thread-safe.
.. method:: loop.call_soon_threadsafe(callback, *args, context=None)
- A thread-safe variant of :meth:`call_soon`. Must be used to
- schedule callbacks *from another thread*.
+ A thread-safe variant of :meth:`call_soon`. When scheduling callbacks from
+ another thread, this function *must* be used, since :meth:`call_soon` is not
+ thread-safe.
Raises :exc:`RuntimeError` if called on a loop that's been closed.
This can happen on a secondary thread when the main application is
@@ -332,7 +347,7 @@ Creating Futures and Tasks
.. method:: loop.create_task(coro, *, name=None, context=None)
- Schedule the execution of a :ref:`coroutine`.
+ Schedule the execution of :ref:`coroutine ` *coro*.
Return a :class:`Task` object.
Third-party event loops can use their own subclass of :class:`Task`
@@ -456,6 +471,12 @@ Opening network connections
*happy_eyeballs_delay*, *interleave*
and *local_addr* should be specified.
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ transport created. To close the socket, call the transport's
+ :meth:`~asyncio.BaseTransport.close` method.
+
* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
to bind the socket locally. The *local_host* and *local_port*
are looked up using ``getaddrinfo()``, similarly to *host* and *port*.
@@ -489,12 +510,12 @@ Opening network connections
When a server's IPv4 path and protocol are working, but the server's
IPv6 path and protocol are not working, a dual-stack client
application experiences significant connection delay compared to an
- IPv4-only client. This is undesirable because it causes the dual-
- stack client to have a worse user experience. This document
+ IPv4-only client. This is undesirable because it causes the
+ dual-stack client to have a worse user experience. This document
specifies requirements for algorithms that reduce this user-visible
delay and provides an algorithm.
- For more information: https://tools.ietf.org/html/rfc6555
+ For more information: https://datatracker.ietf.org/doc/html/rfc6555
.. versionchanged:: 3.11
@@ -554,6 +575,12 @@ Opening network connections
transport. If specified, *local_addr* and *remote_addr* should be omitted
(must be :const:`None`).
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ transport created. To close the socket, call the transport's
+ :meth:`~asyncio.BaseTransport.close` method.
+
See :ref:`UDP echo client protocol ` and
:ref:`UDP echo server protocol ` examples.
@@ -665,6 +692,12 @@ Creating network servers
* *sock* can optionally be specified in order to use a preexisting
socket object. If specified, *host* and *port* must not be specified.
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ server created. To close the socket, call the server's
+ :meth:`~asyncio.Server.close` method.
+
* *backlog* is the maximum number of queued connections passed to
:meth:`~socket.socket.listen` (defaults to 100).
@@ -766,6 +799,12 @@ Creating network servers
* *sock* is a preexisting socket object returned from
:meth:`socket.accept `.
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ transport created. To close the socket, call the transport's
+ :meth:`~asyncio.BaseTransport.close` method.
+
* *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over
the accepted connections.
@@ -830,9 +869,14 @@ TLS Upgrade
Upgrade an existing transport-based connection to TLS.
- Return a new transport instance, that the *protocol* must start using
- immediately after the *await*. The *transport* instance passed to
- the *start_tls* method should never be used again.
+ Create a TLS coder/decoder instance and insert it between the *transport*
+ and the *protocol*. The coder/decoder implements both *transport*-facing
+ protocol and *protocol*-facing transport.
+
+ Return the created two-interface instance. After *await*, the *protocol*
+ must stop using the original *transport* and communicate with the returned
+ object only because the coder caches *protocol*-side data and sporadically
+ exchanges extra TLS session packets with *transport*.
Parameters:
@@ -875,7 +919,8 @@ Watching file descriptors
.. method:: loop.remove_reader(fd)
- Stop monitoring the *fd* file descriptor for read availability.
+ Stop monitoring the *fd* file descriptor for read availability. Returns
+ ``True`` if *fd* was previously being monitored for reads.
.. method:: loop.add_writer(fd, callback, *args)
@@ -888,7 +933,8 @@ Watching file descriptors
.. method:: loop.remove_writer(fd)
- Stop monitoring the *fd* file descriptor for write availability.
+ Stop monitoring the *fd* file descriptor for write availability. Returns
+ ``True`` if *fd* was previously being monitored for writes.
See also :ref:`Platform Support ` section
for some limitations of these methods.
@@ -1206,7 +1252,13 @@ Executing code in thread or process pools
pool, cpu_bound)
print('custom process pool', result)
- asyncio.run(main())
+ if __name__ == '__main__':
+ asyncio.run(main())
+
+ Note that the entry point guard (``if __name__ == '__main__'``)
+ is required for option 3 due to the peculiarities of :mod:`multiprocessing`,
+ which is used by :class:`~concurrent.futures.ProcessPoolExecutor`.
+ See :ref:`Safe importing of main module `.
This method returns a :class:`asyncio.Future` object.
@@ -1486,7 +1538,7 @@ Server objects are created by :meth:`loop.create_server`,
:meth:`loop.create_unix_server`, :func:`start_server`,
and :func:`start_unix_server` functions.
-Do not instantiate the class directly.
+Do not instantiate the :class:`Server` class directly.
.. class:: Server
@@ -1577,7 +1629,8 @@ Do not instantiate the class directly.
.. attribute:: sockets
- List of :class:`socket.socket` objects the server is listening on.
+ List of socket-like objects, ``asyncio.trsock.TransportSocket``, which
+ the server is listening on.
.. versionchanged:: 3.7
Prior to Python 3.7 ``Server.sockets`` used to return an
@@ -1586,6 +1639,7 @@ Do not instantiate the class directly.
.. _asyncio-event-loops:
+.. _asyncio-event-loop-implementations:
Event Loop Implementations
==========================
@@ -1608,9 +1662,12 @@ on Unix and :class:`ProactorEventLoop` on Windows.
import asyncio
import selectors
- selector = selectors.SelectSelector()
- loop = asyncio.SelectorEventLoop(selector)
- asyncio.set_event_loop(loop)
+ class MyPolicy(asyncio.DefaultEventLoopPolicy):
+ def new_event_loop(self):
+ selector = selectors.SelectSelector()
+ return asyncio.SelectorEventLoop(selector)
+
+ asyncio.set_event_loop_policy(MyPolicy())
.. availability:: Unix, Windows.
@@ -1632,7 +1689,7 @@ on Unix and :class:`ProactorEventLoop` on Windows.
Abstract base class for asyncio-compliant event loops.
- The :ref:`Event Loop Methods ` section lists all
+ The :ref:`asyncio-event-loop-methods` section lists all
methods that an alternative implementation of ``AbstractEventLoop``
should have defined.
@@ -1663,7 +1720,7 @@ event loop::
print('Hello World')
loop.stop()
- loop = asyncio.get_event_loop()
+ loop = asyncio.new_event_loop()
# Schedule a call to hello_world()
loop.call_soon(hello_world, loop)
@@ -1699,7 +1756,7 @@ after 5 seconds, and then stops the event loop::
else:
loop.stop()
- loop = asyncio.get_event_loop()
+ loop = asyncio.new_event_loop()
# Schedule the first call to display_date()
end_time = loop.time() + 5.0
@@ -1731,7 +1788,7 @@ Wait until a file descriptor received some data using the
# Create a pair of connected file descriptors
rsock, wsock = socketpair()
- loop = asyncio.get_event_loop()
+ loop = asyncio.new_event_loop()
def reader():
data = rsock.recv(100)
diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst
index acbaa6f7faf745..8ffd356f2d1cc3 100644
--- a/Doc/library/asyncio-extending.rst
+++ b/Doc/library/asyncio-extending.rst
@@ -63,12 +63,6 @@ For this purpose the following, *private* constructors are listed:
*context* argument is added.
-.. method:: Task._check_future(future)
-
- Return ``True`` if *future* is attached to the same loop as the task, ``False``
- otherwise.
-
- .. versionadded:: 3.11
Task lifetime support
diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst
index f74f2e6f8935ea..70cec9b2f90248 100644
--- a/Doc/library/asyncio-future.rst
+++ b/Doc/library/asyncio-future.rst
@@ -55,7 +55,7 @@ Future Functions
preferred way for creating new Tasks.
Save a reference to the result of this function, to avoid
- a task disappearing mid execution.
+ a task disappearing mid-execution.
.. versionchanged:: 3.5.1
The function accepts any :term:`awaitable` object.
@@ -85,7 +85,8 @@ Future Object
Future is an :term:`awaitable` object. Coroutines can await on
Future objects until they either have a result or an exception
- set, or until they are cancelled.
+ set, or until they are cancelled. A Future can be awaited multiple
+ times and the result is same.
Typically Futures are used to enable low-level
callback-based code (e.g. in protocols implemented using asyncio
@@ -196,11 +197,6 @@ Future Object
.. versionchanged:: 3.9
Added the *msg* parameter.
- .. deprecated-removed:: 3.11 3.14
- *msg* parameter is ambiguous when multiple :meth:`cancel`
- are called with different cancellation messages.
- The argument will be removed.
-
.. method:: exception()
Return the exception that was set on this Future.
@@ -281,8 +277,3 @@ the Future has a result::
- :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument,
but :func:`concurrent.futures.cancel` does not.
-
- .. deprecated-removed:: 3.11 3.14
- *msg* parameter is ambiguous when multiple :meth:`cancel`
- are called with different cancellation messages.
- The argument will be removed.
diff --git a/Doc/library/asyncio-llapi-index.rst b/Doc/library/asyncio-llapi-index.rst
index 69b550e43f5aa9..9ce48a24444e66 100644
--- a/Doc/library/asyncio-llapi-index.rst
+++ b/Doc/library/asyncio-llapi-index.rst
@@ -19,7 +19,7 @@ Obtaining the Event Loop
- The **preferred** function to get the running event loop.
* - :func:`asyncio.get_event_loop`
- - Get an event loop instance (current or via the policy).
+ - Get an event loop instance (running or current via the current policy).
* - :func:`asyncio.set_event_loop`
- Set the event loop as current via the current policy.
@@ -37,7 +37,7 @@ Event Loop Methods
==================
See also the main documentation section about the
-:ref:`event loop methods `.
+:ref:`asyncio-event-loop-methods`.
.. rubric:: Lifecycle
.. list-table::
@@ -267,7 +267,7 @@ See also the main documentation section about the
.. rubric:: Examples
-* :ref:`Using asyncio.get_event_loop() and loop.run_forever()
+* :ref:`Using asyncio.new_event_loop() and loop.run_forever()
`.
* :ref:`Using loop.call_later() `.
@@ -358,6 +358,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-policy.rst b/Doc/library/asyncio-policy.rst
index ef6a0588506b52..f846f76ca095f4 100644
--- a/Doc/library/asyncio-policy.rst
+++ b/Doc/library/asyncio-policy.rst
@@ -7,22 +7,29 @@
Policies
========
-An event loop policy is a global per-process object that controls
-the management of the event loop. Each event loop has a default
-policy, which can be changed and customized using the policy API.
-
-A policy defines the notion of *context* and manages a
-separate event loop per context. The default policy
-defines *context* to be the current thread.
-
-By using a custom event loop policy, the behavior of
-:func:`get_event_loop`, :func:`set_event_loop`, and
-:func:`new_event_loop` functions can be customized.
+An event loop policy is a global object
+used to get and set the current :ref:`event loop `,
+as well as create new event loops.
+The default policy can be :ref:`replaced ` with
+:ref:`built-in alternatives `
+to use different event loop implementations,
+or substituted by a :ref:`custom policy `
+that can override these behaviors.
+
+The :ref:`policy object `
+gets and sets a separate event loop per *context*.
+This is per-thread by default,
+though custom policies could define *context* differently.
+
+Custom event loop policies can control the behavior of
+:func:`get_event_loop`, :func:`set_event_loop`, and :func:`new_event_loop`.
Policy objects should implement the APIs defined
in the :class:`AbstractEventLoopPolicy` abstract base class.
+.. _asyncio-policy-get-set:
+
Getting and Setting the Policy
==============================
@@ -40,6 +47,8 @@ for the current process:
If *policy* is set to ``None``, the default policy is restored.
+.. _asyncio-policy-objects:
+
Policy Objects
==============
@@ -86,6 +95,8 @@ The abstract event loop policy base class is defined as follows:
This function is Unix specific.
+.. _asyncio-policy-builtin:
+
asyncio ships with the following built-in policies:
@@ -101,6 +112,12 @@ asyncio ships with the following built-in policies:
On Windows, :class:`ProactorEventLoop` is now used by default.
+ .. note::
+ In Python versions 3.10.9, 3.11.1 and 3.12 the :meth:`get_event_loop`
+ method of the default asyncio policy emits a :exc:`DeprecationWarning`
+ if there is no running event loop and no current loop is set.
+ In some future Python release this will become an error.
+
.. class:: WindowsSelectorEventLoopPolicy
@@ -117,6 +134,7 @@ asyncio ships with the following built-in policies:
.. availability:: Windows.
+
.. _asyncio-watchers:
Process Watchers
@@ -270,6 +288,8 @@ implementation used by the asyncio event loop:
.. versionadded:: 3.9
+.. _asyncio-custom-policies:
+
Custom Policies
===============
diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst
index 8b67f4b8957ef6..7bc906eaafc1f2 100644
--- a/Doc/library/asyncio-protocol.rst
+++ b/Doc/library/asyncio-protocol.rst
@@ -156,7 +156,8 @@ Base Transport
will be received. After all buffered data is flushed, the
protocol's :meth:`protocol.connection_lost()
` method will be called with
- :const:`None` as its argument.
+ :const:`None` as its argument. The transport should not be
+ used once it is closed.
.. method:: BaseTransport.is_closing()
@@ -553,7 +554,7 @@ accept factories that return streaming protocols.
a connection is open.
However, :meth:`protocol.eof_received() `
- is called at most once. Once `eof_received()` is called,
+ is called at most once. Once ``eof_received()`` is called,
``data_received()`` is not called anymore.
.. method:: Protocol.eof_received()
diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst
index d0df1db892f9ec..4abe7b6e087a60 100644
--- a/Doc/library/asyncio-runner.rst
+++ b/Doc/library/asyncio-runner.rst
@@ -75,7 +75,9 @@ Runner context manager
:ref:`asyncio-debug-mode` settings.
*loop_factory* could be used for overriding the loop creation.
- :func:`asyncio.new_event_loop` is used if ``None``.
+ It is the responsibility of the *loop_factory* to set the created loop as the
+ current one. By default :func:`asyncio.new_event_loop` is used and set as
+ current event loop with :func:`asyncio.set_event_loop` if *loop_factory* is ``None``.
Basically, :func:`asyncio.run()` example can be rewritten with the runner usage::
diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst
index 72355d356f2052..e9d466d95e547e 100644
--- a/Doc/library/asyncio-stream.rst
+++ b/Doc/library/asyncio-stream.rst
@@ -52,6 +52,7 @@ and work with streams:
limit=None, ssl=None, family=0, proto=0, \
flags=0, sock=None, local_addr=None, \
server_hostname=None, ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, \
happy_eyeballs_delay=None, interleave=None)
Establish a network connection and return a pair of
@@ -67,6 +68,12 @@ and work with streams:
The rest of the arguments are passed directly to
:meth:`loop.create_connection`.
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ :class:`StreamWriter` created. To close the socket, call its
+ :meth:`~asyncio.StreamWriter.close` method.
+
.. versionchanged:: 3.7
Added the *ssl_handshake_timeout* parameter.
@@ -76,6 +83,9 @@ and work with streams:
.. versionchanged:: 3.10
Removed the *loop* parameter.
+ .. versionchanged:: 3.11
+ Added the *ssl_shutdown_timeout* parameter.
+
.. coroutinefunction:: start_server(client_connected_cb, host=None, \
port=None, *, limit=None, \
@@ -83,7 +93,7 @@ and work with streams:
flags=socket.AI_PASSIVE, sock=None, \
backlog=100, ssl=None, reuse_address=None, \
reuse_port=None, ssl_handshake_timeout=None, \
- start_serving=True)
+ ssl_shutdown_timeout=None, start_serving=True)
Start a socket server.
@@ -103,18 +113,27 @@ and work with streams:
The rest of the arguments are passed directly to
:meth:`loop.create_server`.
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ server created. To close the socket, call the server's
+ :meth:`~asyncio.Server.close` method.
+
.. versionchanged:: 3.7
Added the *ssl_handshake_timeout* and *start_serving* parameters.
.. versionchanged:: 3.10
Removed the *loop* parameter.
+ .. versionchanged:: 3.11
+ Added the *ssl_shutdown_timeout* parameter.
+
.. rubric:: Unix Sockets
.. coroutinefunction:: open_unix_connection(path=None, *, limit=None, \
ssl=None, sock=None, server_hostname=None, \
- ssl_handshake_timeout=None)
+ ssl_handshake_timeout=None, ssl_shutdown_timeout=None)
Establish a Unix socket connection and return a pair of
``(reader, writer)``.
@@ -123,6 +142,12 @@ and work with streams:
See also the documentation of :meth:`loop.create_unix_connection`.
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ :class:`StreamWriter` created. To close the socket, call its
+ :meth:`~asyncio.StreamWriter.close` method.
+
.. availability:: Unix.
.. versionchanged:: 3.7
@@ -132,10 +157,14 @@ and work with streams:
.. versionchanged:: 3.10
Removed the *loop* parameter.
+ .. versionchanged:: 3.11
+ Added the *ssl_shutdown_timeout* parameter.
+
.. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \
*, limit=None, sock=None, backlog=100, ssl=None, \
- ssl_handshake_timeout=None, start_serving=True)
+ ssl_handshake_timeout=None, \
+ ssl_shutdown_timeout=None, start_serving=True)
Start a Unix socket server.
@@ -143,6 +172,12 @@ and work with streams:
See also the documentation of :meth:`loop.create_unix_server`.
+ .. note::
+
+ The *sock* argument transfers ownership of the socket to the
+ server created. To close the socket, call the server's
+ :meth:`~asyncio.Server.close` method.
+
.. availability:: Unix.
.. versionchanged:: 3.7
@@ -152,6 +187,9 @@ and work with streams:
.. versionchanged:: 3.10
Removed the *loop* parameter.
+ .. versionchanged:: 3.11
+ Added the *ssl_shutdown_timeout* parameter.
+
StreamReader
============
@@ -159,7 +197,8 @@ StreamReader
.. class:: StreamReader
Represents a reader object that provides APIs to read data
- from the IO stream.
+ from the IO stream. As an :term:`asynchronous iterable`, the
+ object supports the :keyword:`async for` statement.
It is not recommended to instantiate *StreamReader* objects
directly; use :func:`open_connection` and :func:`start_server`
@@ -167,12 +206,20 @@ StreamReader
.. coroutinemethod:: read(n=-1)
- Read up to *n* bytes. If *n* is not provided, or set to ``-1``,
- read until EOF and return all read bytes.
+ Read up to *n* bytes from the stream.
+ If *n* is not provided or set to ``-1``,
+ read until EOF, then return all read :class:`bytes`.
If EOF was received and the internal buffer is empty,
return an empty ``bytes`` object.
+ If *n* is ``0``, return an empty ``bytes`` object immediately.
+
+ If *n* is positive, return at most *n* available ``bytes``
+ as soon as at least 1 byte is available in the internal buffer.
+ If EOF is received before any byte is read, return an empty
+ ``bytes`` object.
+
.. coroutinemethod:: readline()
Read one line, where "line" is a sequence of bytes
@@ -192,7 +239,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.
@@ -256,7 +303,8 @@ StreamWriter
The method closes the stream and the underlying socket.
- The method should be used along with the ``wait_closed()`` method::
+ The method should be used, though not mandatory,
+ along with the ``wait_closed()`` method::
stream.close()
await stream.wait_closed()
@@ -311,7 +359,7 @@ StreamWriter
handshake to complete before aborting the connection. ``60.0`` seconds
if ``None`` (default).
- .. versionadded:: 3.8
+ .. versionadded:: 3.11
.. method:: is_closing()
@@ -325,7 +373,8 @@ StreamWriter
Wait until the stream is closed.
Should be called after :meth:`close` to wait until the underlying
- connection is closed.
+ connection is closed, ensuring that all data has been flushed
+ before e.g. exiting the program.
.. versionadded:: 3.7
@@ -355,6 +404,7 @@ TCP echo client using the :func:`asyncio.open_connection` function::
print('Close the connection')
writer.close()
+ await writer.wait_closed()
asyncio.run(tcp_echo_client('Hello World!'))
@@ -387,6 +437,7 @@ TCP echo server using the :func:`asyncio.start_server` function::
print("Close the connection")
writer.close()
+ await writer.wait_closed()
async def main():
server = await asyncio.start_server(
@@ -443,6 +494,7 @@ Simple example querying HTTP headers of the URL passed on the command line::
# Ignore the body, close the socket
writer.close()
+ await writer.wait_closed()
url = sys.argv[1]
asyncio.run(print_http_headers(url))
@@ -488,6 +540,7 @@ Coroutine waiting until a socket receives data using the
# Got data, we are done: close the socket
print("Received:", data.decode())
writer.close()
+ await writer.wait_closed()
# Close the second socket
wsock.close()
diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst
index e5000532a895dd..4274638c5e8625 100644
--- a/Doc/library/asyncio-subprocess.rst
+++ b/Doc/library/asyncio-subprocess.rst
@@ -124,6 +124,7 @@ Constants
=========
.. data:: asyncio.subprocess.PIPE
+ :module:
Can be passed to the *stdin*, *stdout* or *stderr* parameters.
@@ -137,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
@@ -157,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`
@@ -171,7 +175,7 @@ their completion.
* the :meth:`~asyncio.subprocess.Process.communicate` and
:meth:`~asyncio.subprocess.Process.wait` methods don't have a
- *timeout* parameter: use the :func:`wait_for` function;
+ *timeout* parameter: use the :func:`~asyncio.wait_for` function;
* the :meth:`Process.wait() ` method
is asynchronous, whereas :meth:`subprocess.Popen.wait` method
diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst
index 141733ee2c8001..05bdf5488af143 100644
--- a/Doc/library/asyncio-sync.rst
+++ b/Doc/library/asyncio-sync.rst
@@ -345,7 +345,7 @@ BoundedSemaphore
Barrier
=======
-.. class:: Barrier(parties, action=None)
+.. class:: Barrier(parties)
A barrier object. Not thread-safe.
@@ -411,8 +411,8 @@ Barrier
...
async with barrier as position:
if position == 0:
- # Only one task print this
- print('End of *draining phasis*')
+ # Only one task prints this
+ print('End of *draining phase*')
This method may raise a :class:`BrokenBarrierError` exception if the
barrier is broken or reset while a task is waiting.
@@ -429,7 +429,7 @@ Barrier
Put the barrier into a broken state. This causes any active or future
calls to :meth:`wait` to fail with the :class:`BrokenBarrierError`.
- Use this for example if one of the taks needs to abort, to avoid infinite
+ Use this for example if one of the tasks needs to abort, to avoid infinite
waiting tasks.
.. attribute:: parties
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index 8e3d49dcf9d717..550a84ebae39ee 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -18,6 +18,10 @@ and Tasks.
Coroutines
==========
+**Source code:** :source:`Lib/asyncio/coroutines.py`
+
+----------------------------------------------------
+
:term:`Coroutines ` declared with the async/await syntax is the
preferred way of writing asyncio applications. For example, the following
snippet of code prints "hello", waits 1 second,
@@ -40,7 +44,7 @@ be executed::
>>> main()
-To actually run a coroutine, asyncio provides three main mechanisms:
+To actually run a coroutine, asyncio provides the following mechanisms:
* The :func:`asyncio.run` function to run the top-level
entry point "main()" function (see the above example.)
@@ -103,6 +107,29 @@ To actually run a coroutine, asyncio provides three main mechanisms:
world
finished at 17:14:34
+* The :class:`asyncio.TaskGroup` class provides a more modern
+ alternative to :func:`create_task`.
+ Using this API, the last example becomes::
+
+ async def main():
+ async with asyncio.TaskGroup() as tg:
+ task1 = tg.create_task(
+ say_after(1, 'hello'))
+
+ task2 = tg.create_task(
+ say_after(2, 'world'))
+
+ print(f"started at {time.strftime('%X')}")
+
+ # The await is implicit when the context manager exits.
+
+ print(f"finished at {time.strftime('%X')}")
+
+ The timing and output should be the same as for the previous version.
+
+ .. versionadded:: 3.11
+ :class:`asyncio.TaskGroup`.
+
.. _asyncio-awaitables:
@@ -207,6 +234,10 @@ is :meth:`loop.run_in_executor`.
Creating Tasks
==============
+**Source code:** :source:`Lib/asyncio/tasks.py`
+
+-----------------------------------------------
+
.. function:: create_task(coro, *, name=None, context=None)
Wrap the *coro* :ref:`coroutine ` into a :class:`Task`
@@ -223,10 +254,32 @@ Creating Tasks
:exc:`RuntimeError` is raised if there is no running loop in
current thread.
+ .. note::
+
+ :meth:`asyncio.TaskGroup.create_task` is a newer alternative
+ that allows for convenient waiting for a group of related tasks.
+
.. important::
Save a reference to the result of this function, to avoid
- a task disappearing mid execution.
+ 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::
+
+ background_tasks = set()
+
+ 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
@@ -237,6 +290,101 @@ Creating Tasks
Added the *context* parameter.
+Task Cancellation
+=================
+
+Tasks can easily and safely be cancelled.
+When a task is cancelled, :exc:`asyncio.CancelledError` will be raised
+in the task at the next opportunity.
+
+It is recommended that coroutines use ``try/finally`` blocks to robustly
+perform clean-up logic. In case :exc:`asyncio.CancelledError`
+is explicitly caught, it should generally be propagated when
+clean-up is complete. :exc:`asyncio.CancelledError` directly subclasses
+:exc:`BaseException` so most code will not need to be aware of it.
+
+The asyncio components that enable structured concurrency, like
+:class:`asyncio.TaskGroup` and :func:`asyncio.timeout`,
+are implemented using cancellation internally and might misbehave if
+a coroutine swallows :exc:`asyncio.CancelledError`. Similarly, user code
+should not generally call :meth:`uncancel `.
+However, in cases when suppressing :exc:`asyncio.CancelledError` is
+truly desired, it is necessary to also call ``uncancel()`` to completely
+remove the cancellation state.
+
+.. _taskgroups:
+
+Task Groups
+===========
+
+Task groups combine a task creation API with a convenient
+and reliable way to wait for all tasks in the group to finish.
+
+.. class:: TaskGroup()
+
+ An :ref:`asynchronous context manager `
+ holding a group of tasks.
+ Tasks can be added to the group using :meth:`create_task`.
+ All tasks are awaited when the context manager exits.
+
+ .. versionadded:: 3.11
+
+ .. method:: create_task(coro, *, name=None, context=None)
+
+ Create a task in this task group.
+ The signature matches that of :func:`asyncio.create_task`.
+
+Example::
+
+ async def main():
+ async with asyncio.TaskGroup() as tg:
+ task1 = tg.create_task(some_coro(...))
+ task2 = tg.create_task(another_coro(...))
+ print("Both tasks have completed now.")
+
+The ``async with`` statement will wait for all tasks in the group to finish.
+While waiting, new tasks may still be added to the group
+(for example, by passing ``tg`` into one of the coroutines
+and calling ``tg.create_task()`` in that coroutine).
+Once the last task has finished and the ``async with`` block is exited,
+no new tasks may be added to the group.
+
+The first time any of the tasks belonging to the group fails
+with an exception other than :exc:`asyncio.CancelledError`,
+the remaining tasks in the group are cancelled.
+No further tasks can then be added to the group.
+At this point, if the body of the ``async with`` statement is still active
+(i.e., :meth:`~object.__aexit__` hasn't been called yet),
+the task directly containing the ``async with`` statement is also cancelled.
+The resulting :exc:`asyncio.CancelledError` will interrupt an ``await``,
+but it will not bubble out of the containing ``async with`` statement.
+
+Once all tasks have finished, if any tasks have failed
+with an exception other than :exc:`asyncio.CancelledError`,
+those exceptions are combined in an
+:exc:`ExceptionGroup` or :exc:`BaseExceptionGroup`
+(as appropriate; see their documentation)
+which is then raised.
+
+Two base exceptions are treated specially:
+If any task fails with :exc:`KeyboardInterrupt` or :exc:`SystemExit`,
+the task group still cancels the remaining tasks and waits for them,
+but then the initial :exc:`KeyboardInterrupt` or :exc:`SystemExit`
+is re-raised instead of :exc:`ExceptionGroup` or :exc:`BaseExceptionGroup`.
+
+If the body of the ``async with`` statement exits with an exception
+(so :meth:`~object.__aexit__` is called with an exception set),
+this is treated the same as if one of the tasks failed:
+the remaining tasks are cancelled and then waited for,
+and non-cancellation exceptions are grouped into an
+exception group and raised.
+The exception passed into :meth:`~object.__aexit__`,
+unless it is :exc:`asyncio.CancelledError`,
+is also included in the exception group.
+The same special case is made for
+:exc:`KeyboardInterrupt` and :exc:`SystemExit` as in the previous paragraph.
+
+
Sleeping
========
@@ -310,8 +458,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.
+ .. note::
+ A more modern way to create and run tasks concurrently and
+ wait for their completion is :class:`asyncio.TaskGroup`.
.. _asyncio_example_gather:
@@ -385,7 +534,8 @@ Shielding From Cancellation
The statement::
- res = await shield(something())
+ task = asyncio.create_task(something())
+ res = await shield(task)
is equivalent to::
@@ -404,11 +554,19 @@ Shielding From Cancellation
the ``shield()`` function should be combined with a try/except
clause, as follows::
+ task = asyncio.create_task(something())
try:
- res = await shield(something())
+ res = await shield(task)
except CancelledError:
res = None
+ .. important::
+
+ Save a reference to tasks passed to 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.
+
.. versionchanged:: 3.10
Removed the *loop* parameter.
@@ -420,6 +578,119 @@ Shielding From Cancellation
Timeouts
========
+.. coroutinefunction:: timeout(delay)
+
+ An :ref:`asynchronous context manager `
+ that can be used to limit the amount of time spent waiting on
+ something.
+
+ *delay* can either be ``None``, or a float/int number of
+ seconds to wait. If *delay* is ``None``, no time limit will
+ be applied; this can be useful if the delay is unknown when
+ the context manager is created.
+
+ In either case, the context manager can be rescheduled after
+ creation using :meth:`Timeout.reschedule`.
+
+ Example::
+
+ async def main():
+ async with asyncio.timeout(10):
+ await long_running_task()
+
+ If ``long_running_task`` takes more than 10 seconds to complete,
+ the context manager will cancel the current task and handle
+ the resulting :exc:`asyncio.CancelledError` internally, transforming it
+ into an :exc:`asyncio.TimeoutError` which can be caught and handled.
+
+ .. note::
+
+ The :func:`asyncio.timeout` context manager is what transforms
+ the :exc:`asyncio.CancelledError` into an :exc:`asyncio.TimeoutError`,
+ which means the :exc:`asyncio.TimeoutError` can only be caught
+ *outside* of the context manager.
+
+ Example of catching :exc:`asyncio.TimeoutError`::
+
+ async def main():
+ try:
+ async with asyncio.timeout(10):
+ await long_running_task()
+ except TimeoutError:
+ print("The long operation timed out, but we've handled it.")
+
+ print("This statement will run regardless.")
+
+ The context manager produced by :func:`asyncio.timeout` can be
+ rescheduled to a different deadline and inspected.
+
+ .. class:: Timeout(when)
+
+ An :ref:`asynchronous context manager `
+ for cancelling overdue coroutines.
+
+ ``when`` should be an absolute time at which the context should time out,
+ as measured by the event loop's clock:
+
+ - If ``when`` is ``None``, the timeout will never trigger.
+ - If ``when < loop.time()``, the timeout will trigger on the next
+ iteration of the event loop.
+
+ .. method:: when() -> float | None
+
+ Return the current deadline, or ``None`` if the current
+ deadline is not set.
+
+ .. method:: reschedule(when: float | None)
+
+ Reschedule the timeout.
+
+ .. method:: expired() -> bool
+
+ Return whether the context manager has exceeded its deadline
+ (expired).
+
+ Example::
+
+ async def main():
+ try:
+ # We do not know the timeout when starting, so we pass ``None``.
+ async with asyncio.timeout(None) as cm:
+ # We know the timeout now, so we reschedule it.
+ new_deadline = get_running_loop().time() + 10
+ cm.reschedule(new_deadline)
+
+ await long_running_task()
+ except TimeoutError:
+ pass
+
+ if cm.expired():
+ print("Looks like we haven't finished on time.")
+
+ Timeout context managers can be safely nested.
+
+ .. versionadded:: 3.11
+
+.. coroutinefunction:: timeout_at(when)
+
+ Similar to :func:`asyncio.timeout`, except *when* is the absolute time
+ to stop waiting, or ``None``.
+
+ Example::
+
+ async def main():
+ loop = get_running_loop()
+ deadline = loop.time() + 20
+ try:
+ async with asyncio.timeout_at(deadline):
+ await long_running_task()
+ except TimeoutError:
+ print("The long operation timed out, but we've handled it.")
+
+ print("This statement will run regardless.")
+
+ .. versionadded:: 3.11
+
.. coroutinefunction:: wait_for(aw, timeout)
Wait for the *aw* :ref:`awaitable `
@@ -486,7 +757,7 @@ Waiting Primitives
iterable concurrently and block until the condition specified
by *return_when*.
- The *aws* iterable must not be empty.
+ The *aws* iterable must not be empty and generators yielding tasks are not accepted.
Returns two sets of Tasks/Futures: ``(done, pending)``.
@@ -534,16 +805,14 @@ Waiting Primitives
.. function:: as_completed(aws, *, timeout=None)
Run :ref:`awaitable objects ` in the *aws*
- iterable concurrently. Return an iterator of coroutines.
+ iterable concurrently. Generators yielding tasks are not accepted
+ as *aws* iterable. Return an iterator of coroutines.
Each coroutine returned can be awaited to get the earliest next
result from the iterable of the remaining awaitables.
Raises :exc:`TimeoutError` if the timeout occurs before
all Futures are done.
- .. versionchanged:: 3.10
- Removed the *loop* parameter.
-
Example::
for coro in as_completed(aws):
@@ -602,17 +871,17 @@ Running in Threads
# blocking_io complete at 19:50:54
# finished main at 19:50:54
- Directly calling `blocking_io()` in any coroutine would block the event loop
+ Directly calling ``blocking_io()`` in any coroutine would block the event loop
for its duration, resulting in an additional 1 second of run time. Instead,
- by using `asyncio.to_thread()`, we can run it in a separate thread without
+ by using ``asyncio.to_thread()``, we can run it in a separate thread without
blocking the event loop.
.. note::
- Due to the :term:`GIL`, `asyncio.to_thread()` can typically only be used
+ Due to the :term:`GIL`, ``asyncio.to_thread()`` can typically only be used
to make IO-bound functions non-blocking. However, for extension modules
that release the GIL or alternative Python implementations that don't
- have one, `asyncio.to_thread()` can also be used for CPU-bound functions.
+ have one, ``asyncio.to_thread()`` can also be used for CPU-bound functions.
.. versionadded:: 3.9
@@ -688,10 +957,17 @@ Introspection
.. versionadded:: 3.7
+.. function:: iscoroutine(obj)
+
+ Return ``True`` if *obj* is a coroutine object.
+
+ .. versionadded:: 3.4
+
+
Task Object
===========
-.. class:: Task(coro, *, loop=None, name=None)
+.. class:: Task(coro, *, loop=None, name=None, context=None)
A :class:`Future-like ` object that runs a Python
:ref:`coroutine `. Not thread-safe.
@@ -726,9 +1002,10 @@ Task Object
APIs except :meth:`Future.set_result` and
:meth:`Future.set_exception`.
- Tasks support the :mod:`contextvars` module. When a Task
- is created it copies the current context and later runs its
- coroutine in the copied context.
+ An optional keyword-only *context* argument allows specifying a
+ custom :class:`contextvars.Context` for the *coro* to run in.
+ If no *context* is provided, the Task copies the current context
+ and later runs its coroutine in the copied context.
.. versionchanged:: 3.7
Added support for the :mod:`contextvars` module.
@@ -740,75 +1017,8 @@ Task Object
Deprecation warning is emitted if *loop* is not specified
and there is no running event loop.
- .. method:: cancel(msg=None)
-
- Request the Task to be cancelled.
-
- This arranges for a :exc:`CancelledError` exception to be thrown
- into the wrapped coroutine on the next cycle of the event loop.
-
- The coroutine then has a chance to clean up or even deny the
- request by suppressing the exception with a :keyword:`try` ...
- ... ``except CancelledError`` ... :keyword:`finally` block.
- Therefore, unlike :meth:`Future.cancel`, :meth:`Task.cancel` does
- not guarantee that the Task will be cancelled, although
- suppressing cancellation completely is not common and is actively
- discouraged.
-
- .. versionchanged:: 3.9
- Added the *msg* parameter.
-
- .. deprecated-removed:: 3.11 3.14
- *msg* parameter is ambiguous when multiple :meth:`cancel`
- are called with different cancellation messages.
- The argument will be removed.
-
- .. _asyncio_example_task_cancel:
-
- The following example illustrates how coroutines can intercept
- the cancellation request::
-
- async def cancel_me():
- print('cancel_me(): before sleep')
-
- try:
- # Wait for 1 hour
- await asyncio.sleep(3600)
- except asyncio.CancelledError:
- print('cancel_me(): cancel sleep')
- raise
- finally:
- print('cancel_me(): after sleep')
-
- async def main():
- # Create a "cancel_me" Task
- task = asyncio.create_task(cancel_me())
-
- # Wait for 1 second
- await asyncio.sleep(1)
-
- task.cancel()
- try:
- await task
- except asyncio.CancelledError:
- print("main(): cancel_me is cancelled now")
-
- asyncio.run(main())
-
- # Expected output:
- #
- # cancel_me(): before sleep
- # cancel_me(): cancel sleep
- # cancel_me(): after sleep
- # main(): cancel_me is cancelled now
-
- .. method:: cancelled()
-
- Return ``True`` if the Task is *cancelled*.
-
- The Task is *cancelled* when the cancellation was requested with
- :meth:`cancel` and the wrapped coroutine propagated the
- :exc:`CancelledError` exception thrown into it.
+ .. versionchanged:: 3.11
+ Added the *context* parameter.
.. method:: done()
@@ -894,7 +1104,7 @@ Task Object
The *limit* argument is passed to :meth:`get_stack` directly.
The *file* argument is an I/O stream to which the output
- is written; by default output is written to :data:`sys.stderr`.
+ is written; by default output is written to :data:`sys.stdout`.
.. method:: get_coro()
@@ -923,3 +1133,129 @@ Task Object
in the :func:`repr` output of a task object.
.. versionadded:: 3.8
+
+ .. method:: cancel(msg=None)
+
+ Request the Task to be cancelled.
+
+ This arranges for a :exc:`CancelledError` exception to be thrown
+ into the wrapped coroutine on the next cycle of the event loop.
+
+ The coroutine then has a chance to clean up or even deny the
+ request by suppressing the exception with a :keyword:`try` ...
+ ... ``except CancelledError`` ... :keyword:`finally` block.
+ Therefore, unlike :meth:`Future.cancel`, :meth:`Task.cancel` does
+ not guarantee that the Task will be cancelled, although
+ suppressing cancellation completely is not common and is actively
+ discouraged. Should the coroutine nevertheless decide to suppress
+ the cancellation, it needs to call :meth:`Task.uncancel` in addition
+ to catching the exception.
+
+ .. versionchanged:: 3.9
+ Added the *msg* parameter.
+
+ .. versionchanged:: 3.11
+ The ``msg`` parameter is propagated from cancelled task to its awaiter.
+
+ .. _asyncio_example_task_cancel:
+
+ The following example illustrates how coroutines can intercept
+ the cancellation request::
+
+ async def cancel_me():
+ print('cancel_me(): before sleep')
+
+ try:
+ # Wait for 1 hour
+ await asyncio.sleep(3600)
+ except asyncio.CancelledError:
+ print('cancel_me(): cancel sleep')
+ raise
+ finally:
+ print('cancel_me(): after sleep')
+
+ async def main():
+ # Create a "cancel_me" Task
+ task = asyncio.create_task(cancel_me())
+
+ # Wait for 1 second
+ await asyncio.sleep(1)
+
+ task.cancel()
+ try:
+ await task
+ except asyncio.CancelledError:
+ print("main(): cancel_me is cancelled now")
+
+ asyncio.run(main())
+
+ # Expected output:
+ #
+ # cancel_me(): before sleep
+ # cancel_me(): cancel sleep
+ # cancel_me(): after sleep
+ # main(): cancel_me is cancelled now
+
+ .. method:: cancelled()
+
+ Return ``True`` if the Task is *cancelled*.
+
+ The Task is *cancelled* when the cancellation was requested with
+ :meth:`cancel` and the wrapped coroutine propagated the
+ :exc:`CancelledError` exception thrown into it.
+
+ .. method:: uncancel()
+
+ Decrement the count of cancellation requests to this Task.
+
+ Returns the remaining number of cancellation requests.
+
+ Note that once execution of a cancelled task completed, further
+ calls to :meth:`uncancel` are ineffective.
+
+ .. versionadded:: 3.11
+
+ This method is used by asyncio's internals and isn't expected to be
+ used by end-user code. In particular, if a Task gets successfully
+ uncancelled, this allows for elements of structured concurrency like
+ :ref:`taskgroups` and :func:`asyncio.timeout` to continue running,
+ isolating cancellation to the respective structured block.
+ For example::
+
+ async def make_request_with_timeout():
+ try:
+ async with asyncio.timeout(1):
+ # Structured block affected by the timeout:
+ await make_request()
+ await make_another_request()
+ except TimeoutError:
+ log("There was a timeout")
+ # Outer code not affected by the timeout:
+ await unrelated_code()
+
+ While the block with ``make_request()`` and ``make_another_request()``
+ might get cancelled due to the timeout, ``unrelated_code()`` should
+ continue running even in case of the timeout. This is implemented
+ with :meth:`uncancel`. :class:`TaskGroup` context managers use
+ :func:`uncancel` in a similar fashion.
+
+ If end-user code is, for some reason, suppresing cancellation by
+ catching :exc:`CancelledError`, it needs to call this method to remove
+ the cancellation state.
+
+ .. method:: cancelling()
+
+ Return the number of pending cancellation requests to this Task, i.e.,
+ the number of calls to :meth:`cancel` less the number of
+ :meth:`uncancel` calls.
+
+ Note that if this number is greater than zero but the Task is
+ still executing, :meth:`cancelled` will still return ``False``.
+ This is because this number can be lowered by calling :meth:`uncancel`,
+ which can lead to the task not being cancelled after all if the
+ cancellation requests go down to zero.
+
+ This method is used by asyncio's internals and isn't expected to be
+ used by end-user code. See :meth:`uncancel` for more details.
+
+ .. versionadded:: 3.11
diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst
index 8f4d55a9de059a..c6a046f534e9a1 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
@@ -57,6 +56,19 @@ Additionally, there are **low-level** APIs for
* :ref:`bridge ` callback-based libraries and code
with async/await syntax.
+You can experiment with an ``asyncio`` concurrent context in the REPL:
+
+.. code-block:: pycon
+
+ $ python -m asyncio
+ asyncio REPL ...
+ Use "await" directly instead of "asyncio.run()".
+ Type "help", "copyright", "credits" or "license" for more information.
+ >>> import asyncio
+ >>> await asyncio.sleep(10, result='hello')
+ 'hello'
+
+.. include:: ../includes/wasm-notavail.rst
.. We use the "rubric" directive here to avoid creating
the "Reference" subsection in the TOC.
diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst
index e481e13db76f70..a3a4e90d05277e 100644
--- a/Doc/library/asyncore.rst
+++ b/Doc/library/asyncore.rst
@@ -13,8 +13,9 @@
**Source code:** :source:`Lib/asyncore.py`
-.. deprecated:: 3.6
- :mod:`asyncore` will be removed in Python 3.12 (:pep:`594`).
+.. deprecated-removed:: 3.6 3.12
+ The :mod:`asyncore` module is deprecated
+ (see :pep:`PEP 594 <594#asyncore>` for details).
Please use :mod:`asyncio` instead.
--------------
@@ -27,6 +28,8 @@
This module provides the basic infrastructure for writing asynchronous socket
service clients and servers.
+.. include:: ../includes/wasm-notavail.rst
+
There are only two ways to have a program on a single processor do "more than
one thing at a time." Multi-threaded programming is the simplest and most
popular way to do it, but there is another very different technique, that lets
diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst
index f7f038107d11fe..a2bd85b31c9a8d 100644
--- a/Doc/library/atexit.rst
+++ b/Doc/library/atexit.rst
@@ -20,6 +20,9 @@ at interpreter termination time they will be run in the order ``C``, ``B``,
program is killed by a signal not handled by Python, when a Python fatal
internal error is detected, or when :func:`os._exit` is called.
+**Note:** The effect of registering or unregistering functions from within
+a cleanup function is undefined.
+
.. versionchanged:: 3.7
When used with C-API subinterpreters, registered functions
are local to the interpreter they were registered in.
diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst
index eae206084f0900..1f96575d08f5b1 100644
--- a/Doc/library/audioop.rst
+++ b/Doc/library/audioop.rst
@@ -5,8 +5,9 @@
:synopsis: Manipulate raw audio data.
:deprecated:
-.. deprecated:: 3.11
- The :mod:`audioop` module is deprecated (see :pep:`594` for details).
+.. deprecated-removed:: 3.11 3.13
+ 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 4ff038c8d29f1a..d5b6af8c1928ef 100644
--- a/Doc/library/base64.rst
+++ b/Doc/library/base64.rst
@@ -53,11 +53,13 @@ The modern interface provides:
Encode the :term:`bytes-like object` *s* using Base64 and return the encoded
:class:`bytes`.
- Optional *altchars* must be a :term:`bytes-like object` of at least
- length 2 (additional characters are ignored) which specifies an alternative
- alphabet for the ``+`` and ``/`` characters. This allows an application to e.g.
- generate URL or filesystem safe Base64 strings. The default is ``None``, for
- which the standard Base64 alphabet is used.
+ Optional *altchars* must be a :term:`bytes-like object` of length 2 which
+ specifies an alternative alphabet for the ``+`` and ``/`` characters.
+ This allows an application to e.g. generate URL or filesystem safe Base64
+ strings. The default is ``None``, for which the standard Base64 alphabet is used.
+
+ May assert or raise a :exc:`ValueError` if the length of *altchars* is not 2. Raises a
+ :exc:`TypeError` if *altchars* is not a :term:`bytes-like object`.
.. function:: b64decode(s, altchars=None, validate=False)
@@ -65,9 +67,9 @@ The modern interface provides:
Decode the Base64 encoded :term:`bytes-like object` or ASCII string
*s* and return the decoded :class:`bytes`.
- Optional *altchars* must be a :term:`bytes-like object` or ASCII string of
- at least length 2 (additional characters are ignored) which specifies the
- alternative alphabet used instead of the ``+`` and ``/`` characters.
+ Optional *altchars* must be a :term:`bytes-like object` or ASCII string
+ of length 2 which specifies the alternative alphabet used instead of the
+ ``+`` and ``/`` characters.
A :exc:`binascii.Error` exception is raised
if *s* is incorrectly padded.
@@ -80,6 +82,7 @@ The modern interface provides:
For more information about the strict base64 check, see :func:`binascii.a2b_base64`
+ May assert or raise a :exc:`ValueError` if the length of *altchars* is not 2.
.. function:: standard_b64encode(s)
@@ -201,7 +204,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`.
diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst
index 7e4066cd436ad5..d201dc963b5995 100644
--- a/Doc/library/bdb.rst
+++ b/Doc/library/bdb.rst
@@ -20,20 +20,21 @@ The following exception is defined:
The :mod:`bdb` module also defines two classes:
-.. class:: Breakpoint(self, file, line, temporary=0, cond=None, funcname=None)
+.. class:: Breakpoint(self, file, line, temporary=False, cond=None, funcname=None)
This class implements temporary breakpoints, ignore counts, disabling and
(re-)enabling, and conditionals.
Breakpoints are indexed by number through a list called :attr:`bpbynumber`
- and by ``(file, line)`` pairs through :attr:`bplist`. The former points to a
- single instance of class :class:`Breakpoint`. The latter points to a list of
- such instances since there may be more than one breakpoint per line.
+ and by ``(file, line)`` pairs through :attr:`bplist`. The former points to
+ a single instance of class :class:`Breakpoint`. The latter points to a list
+ of such instances since there may be more than one breakpoint per line.
- When creating a breakpoint, its associated filename should be in canonical
- form. If a *funcname* is defined, a breakpoint hit will be counted when the
- first line of that function is executed. A conditional breakpoint always
- counts a hit.
+ When creating a breakpoint, its associated :attr:`file name ` should
+ be in canonical form. If a :attr:`funcname` is defined, a breakpoint
+ :attr:`hit ` will be counted when the first line of that function is
+ executed. A :attr:`conditional ` breakpoint always counts a
+ :attr:`hit `.
:class:`Breakpoint` instances have the following methods:
@@ -59,12 +60,12 @@ The :mod:`bdb` module also defines two classes:
Return a string with all the information about the breakpoint, nicely
formatted:
- * The breakpoint number.
- * If it is temporary or not.
- * Its file,line position.
- * The condition that causes a break.
- * If it must be ignored the next N times.
- * The breakpoint hit count.
+ * Breakpoint number.
+ * Temporary status (del or keep).
+ * File/line position.
+ * Break condition.
+ * Number of times to ignore.
+ * Number of times hit.
.. versionadded:: 3.2
@@ -73,6 +74,49 @@ The :mod:`bdb` module also defines two classes:
Print the output of :meth:`bpformat` to the file *out*, or if it is
``None``, to standard output.
+ :class:`Breakpoint` instances have the following attributes:
+
+ .. attribute:: file
+
+ File name of the :class:`Breakpoint`.
+
+ .. attribute:: line
+
+ Line number of the :class:`Breakpoint` within :attr:`file`.
+
+ .. attribute:: temporary
+
+ True if a :class:`Breakpoint` at (file, line) is temporary.
+
+ .. attribute:: cond
+
+ Condition for evaluating a :class:`Breakpoint` at (file, line).
+
+ .. attribute:: funcname
+
+ Function name that defines whether a :class:`Breakpoint` is hit upon
+ entering the function.
+
+ .. attribute:: enabled
+
+ True if :class:`Breakpoint` is enabled.
+
+ .. attribute:: bpbynumber
+
+ Numeric index for a single instance of a :class:`Breakpoint`.
+
+ .. attribute:: bplist
+
+ Dictionary of :class:`Breakpoint` instances indexed by
+ (:attr:`file`, :attr:`line`) tuples.
+
+ .. attribute:: ignore
+
+ Number of times to ignore a :class:`Breakpoint`.
+
+ .. attribute:: hits
+
+ Count of the number of times a :class:`Breakpoint` has been hit.
.. class:: Bdb(skip=None)
@@ -95,9 +139,12 @@ The :mod:`bdb` module also defines two classes:
.. method:: canonic(filename)
- Auxiliary method for getting a filename in a canonical form, that is, as a
- case-normalized (on case-insensitive filesystems) absolute path, stripped
- of surrounding angle brackets.
+ Return canonical form of *filename*.
+
+ For real file names, the canonical form is an operating-system-dependent,
+ :func:`case-normalized ` :func:`absolute path
+ `. A *filename* with angle brackets, such as ``""``
+ generated in interactive mode, is returned unchanged.
.. method:: reset()
@@ -166,45 +213,46 @@ The :mod:`bdb` module also defines two classes:
Normally derived classes don't override the following methods, but they may
if they want to redefine the definition of stopping and breakpoints.
+ .. method:: is_skipped_line(module_name)
+
+ Return True if *module_name* matches any skip pattern.
+
.. method:: stop_here(frame)
- This method checks if the *frame* is somewhere below :attr:`botframe` in
- the call stack. :attr:`botframe` is the frame in which debugging started.
+ Return True if *frame* is below the starting frame in the stack.
.. method:: break_here(frame)
- This method checks if there is a breakpoint in the filename and line
- belonging to *frame* or, at least, in the current function. If the
- breakpoint is a temporary one, this method deletes it.
+ Return True if there is an effective breakpoint for this line.
+
+ Check whether a line or function breakpoint exists and is in effect. Delete temporary
+ breakpoints based on information from :func:`effective`.
.. method:: break_anywhere(frame)
- This method checks if there is a breakpoint in the filename of the current
- frame.
+ Return True if any breakpoint exists for *frame*'s filename.
Derived classes should override these methods to gain control over debugger
operation.
.. method:: user_call(frame, argument_list)
- This method is called from :meth:`dispatch_call` when there is the
- possibility that a break might be necessary anywhere inside the called
- function.
+ Called from :meth:`dispatch_call` if a break might stop inside the
+ called function.
.. method:: user_line(frame)
- This method is called from :meth:`dispatch_line` when either
- :meth:`stop_here` or :meth:`break_here` yields ``True``.
+ Called from :meth:`dispatch_line` when either :meth:`stop_here` or
+ :meth:`break_here` returns ``True``.
.. method:: user_return(frame, return_value)
- This method is called from :meth:`dispatch_return` when :meth:`stop_here`
- yields ``True``.
+ Called from :meth:`dispatch_return` when :meth:`stop_here` returns ``True``.
.. method:: user_exception(frame, exc_info)
- This method is called from :meth:`dispatch_exception` when
- :meth:`stop_here` yields ``True``.
+ Called from :meth:`dispatch_exception` when :meth:`stop_here`
+ returns ``True``.
.. method:: do_clear(arg)
@@ -228,9 +276,9 @@ The :mod:`bdb` module also defines two classes:
Stop when returning from the given frame.
- .. method:: set_until(frame)
+ .. method:: set_until(frame, lineno=None)
- Stop when the line with the line no greater than the current one is
+ Stop when the line with the *lineno* greater than the current one is
reached or when returning from current frame.
.. method:: set_trace([frame])
@@ -253,7 +301,7 @@ The :mod:`bdb` module also defines two classes:
breakpoints. These methods return a string containing an error message if
something went wrong, or ``None`` if all is well.
- .. method:: set_break(filename, lineno, temporary=0, cond, funcname)
+ .. method:: set_break(filename, lineno, temporary=False, cond=None, funcname=None)
Set a new breakpoint. If the *lineno* line doesn't exist for the
*filename* passed as argument, return an error message. The *filename*
@@ -261,8 +309,8 @@ The :mod:`bdb` module also defines two classes:
.. method:: clear_break(filename, lineno)
- Delete the breakpoints in *filename* and *lineno*. If none were set, an
- error message is returned.
+ Delete the breakpoints in *filename* and *lineno*. If none were set,
+ return an error message.
.. method:: clear_bpbynumber(arg)
@@ -272,12 +320,13 @@ The :mod:`bdb` module also defines two classes:
.. method:: clear_all_file_breaks(filename)
- Delete all breakpoints in *filename*. If none were set, an error message
- is returned.
+ Delete all breakpoints in *filename*. If none were set, return an error
+ message.
.. method:: clear_all_breaks()
- Delete all existing breakpoints.
+ Delete all existing breakpoints. If none were set, return an error
+ message.
.. method:: get_bpbynumber(arg)
@@ -290,7 +339,7 @@ The :mod:`bdb` module also defines two classes:
.. method:: get_break(filename, lineno)
- Check if there is a breakpoint for *lineno* of *filename*.
+ Return True if there is a breakpoint for *lineno* in *filename*.
.. method:: get_breaks(filename, lineno)
@@ -311,16 +360,18 @@ The :mod:`bdb` module also defines two classes:
.. method:: get_stack(f, t)
- Get a list of records for a frame and all higher (calling) and lower
- frames, and the size of the higher part.
+ Return a list of (frame, lineno) tuples in a stack trace, and a size.
+
+ The most recently called frame is last in the list. The size is the number
+ of frames below the frame where the debugger was invoked.
.. method:: format_stack_entry(frame_lineno, lprefix=': ')
- Return a string with information about a stack entry, identified by a
- ``(frame, lineno)`` tuple:
+ Return a string with information about a stack entry, which is a
+ ``(frame, lineno)`` tuple. The return string contains:
- * The canonical form of the filename which contains the frame.
- * The function name, or ``""``.
+ * The canonical filename which contains the frame.
+ * The function name or ``""``.
* The input arguments.
* The return value.
* The line of code (if it exists).
@@ -352,20 +403,34 @@ Finally, the module defines the following functions:
.. function:: checkfuncname(b, frame)
- Check whether we should break here, depending on the way the breakpoint *b*
- was set.
+ Return True if we should break here, depending on the way the
+ :class:`Breakpoint` *b* was set.
- If it was set via line number, it checks if ``b.line`` is the same as the one
- in the frame also passed as argument. If the breakpoint was set via function
- name, we have to check we are in the right frame (the right function) and if
- we are in its first executable line.
+ If it was set via line number, it checks if
+ :attr:`b.line ` is the same as the one in *frame*.
+ If the breakpoint was set via
+ :attr:`function name `, we have to check we are in
+ the right *frame* (the right function) and if we are on its first executable
+ line.
.. function:: effective(file, line, frame)
- Determine if there is an effective (active) breakpoint at this line of code.
- Return a tuple of the breakpoint and a boolean that indicates if it is ok
- to delete a temporary breakpoint. Return ``(None, None)`` if there is no
- matching breakpoint.
+ Return ``(active breakpoint, delete temporary flag)`` or ``(None, None)`` as the
+ breakpoint to act upon.
+
+ The *active breakpoint* is the first entry in
+ :attr:`bplist ` for the
+ (:attr:`file `, :attr:`line `)
+ (which must exist) that is :attr:`enabled `, for
+ which :func:`checkfuncname` is True, and that has neither a False
+ :attr:`condition ` nor positive
+ :attr:`ignore ` count. The *flag*, meaning that a
+ temporary breakpoint should be deleted, is False only when the
+ :attr:`cond ` cannot be evaluated (in which case,
+ :attr:`ignore ` count is ignored).
+
+ If no such entry exists, then (None, None) is returned.
+
.. function:: set_trace()
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 19efc2df9483db..21960cb7972e6e 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -6,8 +6,8 @@
representations.
.. index::
- module: uu
- module: base64
+ pair: module; uu
+ pair: module; base64
--------------
@@ -49,7 +49,7 @@ The :mod:`binascii` module defines the following functions:
Added the *backtick* parameter.
-.. function:: a2b_base64(string, strict_mode=False)
+.. function:: a2b_base64(string, /, *, strict_mode=False)
Convert a block of base64 data back to binary and return the binary data. More
than one line may be passed at a time.
@@ -121,8 +121,6 @@ The :mod:`binascii` module defines the following functions:
.. versionchanged:: 3.0
The result is always unsigned.
- 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 edcd4aeb24aa7e..d4abd7a6313dfd 100644
--- a/Doc/library/bisect.rst
+++ b/Doc/library/bisect.rst
@@ -18,6 +18,8 @@ approach. The module is called :mod:`bisect` because it uses a basic bisection
algorithm to do its work. The source code may be most useful as a working
example of the algorithm (the boundary conditions are already right!).
+.. _bisect functions:
+
The following functions are provided:
@@ -35,8 +37,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.
@@ -45,7 +50,7 @@ The following functions are provided:
.. function:: bisect_right(a, x, lo=0, hi=len(a), *, key=None)
bisect(a, x, lo=0, hi=len(a), *, key=None)
- Similar to :func:`bisect_left`, but returns an insertion point which comes
+ Similar to :py:func:`~bisect.bisect_left`, but returns an insertion point which comes
after (to the right of) any existing entries of *x* in *a*.
The returned insertion point *i* partitions the array *a* into two halves so
@@ -53,8 +58,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 +72,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.
+ This function first runs :py:func:`~bisect.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.
@@ -82,17 +89,16 @@ 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), *, key=None)
- Similar to :func:`insort_left`, but inserting *x* in *a* after any existing
+ Similar to :py:func:`~bisect.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.
+ This function first runs :py:func:`~bisect.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.
@@ -116,14 +122,14 @@ thoughts in mind:
they are used. Consequently, if the search functions are used in a loop,
the key function may be called again and again on the same array elements.
If the key function isn't fast, consider wrapping it with
- :func:`functools.cache` to avoid duplicate computations. Alternatively,
+ :py:func:`functools.cache` to avoid duplicate computations. Alternatively,
consider searching an array of precomputed keys to locate the insertion
point (as shown in the examples section below).
.. seealso::
* `Sorted Collections
- `_ is a high performance
+ `_ is a high performance
module that uses *bisect* to managed sorted collections of data.
* The `SortedCollection recipe
@@ -136,7 +142,7 @@ thoughts in mind:
Searching Sorted Lists
----------------------
-The above :func:`bisect` functions are useful for finding insertion points but
+The above `bisect functions`_ are useful for finding insertion points but
can be tricky or awkward to use for common searching tasks. The following five
functions show how to transform them into the standard lookups for sorted
lists::
@@ -182,8 +188,8 @@ Examples
.. _bisect-example:
-The :func:`bisect` function can be useful for numeric table lookups. This
-example uses :func:`bisect` to look up a letter grade for an exam score (say)
+The :py:func:`~bisect.bisect` function can be useful for numeric table lookups. This
+example uses :py:func:`~bisect.bisect` to look up a letter grade for an exam score (say)
based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is
a 'B', and so on::
@@ -194,8 +200,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 :py:func:`~bisect.bisect` and :py:func:`~bisect.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, 'Spielberg'),
+ ... Movie('Titanic', 1997, 'Cameron'),
+ ... Movie('The Birds', 1963, 'Hitchcock'),
+ ... Movie('Aliens', 1986, 'Cameron')
+ ... ]
+
+ >>> # Find the first movie released 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='Spielberg'),
+ Movie(name='Aliens', released=1986, director='Cameron'),
+ 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 +248,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 999892e95f4715..ae5a1598f84b44 100644
--- a/Doc/library/bz2.rst
+++ b/Doc/library/bz2.rst
@@ -206,7 +206,7 @@ Incremental (de)compression
will be set to ``True``.
Attempting to decompress data after the end of stream is reached
- raises an `EOFError`. Any data found after the end of the
+ raises an :exc:`EOFError`. Any data found after the end of the
stream is ignored and saved in the :attr:`~.unused_data` attribute.
.. versionchanged:: 3.5
@@ -303,7 +303,7 @@ Using :class:`BZ2Compressor` for incremental compression:
>>> out = out + comp.flush()
The example above uses a very "nonrandom" stream of data
-(a stream of `b"z"` chunks). Random data tends to compress poorly,
+(a stream of ``b"z"`` chunks). Random data tends to compress poorly,
while ordered, repetitive data usually yields a high compression ratio.
Writing and reading a bzip2-compressed file in binary mode:
diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst
index 7e697408af07bc..295a601a7bf197 100644
--- a/Doc/library/cgi.rst
+++ b/Doc/library/cgi.rst
@@ -15,8 +15,15 @@
single: URL
single: Common Gateway Interface
-.. deprecated:: 3.11
- The :mod:`cgi` module is deprecated (see :pep:`594` for details).
+.. deprecated-removed:: 3.11 3.13
+ The :mod:`cgi` module is deprecated
+ (see :pep:`PEP 594 <594#cgi>` for details and alternatives).
+
+ The :class:`FieldStorage` class can typically be replaced with
+ :func:`urllib.parse.parse_qsl` for ``GET`` and ``HEAD`` requests,
+ and the :mod:`email.message` module or
+ `multipart `_ for ``POST`` and ``PUT``.
+ Most :ref:`utility functions ` have replacements.
--------------
@@ -30,6 +37,7 @@ size of a POST request. POST requests larger than this size will result in a
:exc:`ValueError` being raised during parsing. The default value of this
variable is ``0``, meaning the request size is unlimited.
+.. include:: ../includes/wasm-notavail.rst
Introduction
------------
@@ -292,6 +300,12 @@ algorithms implemented in this module in other circumstances.
``sys.stdin``). The *keep_blank_values*, *strict_parsing* and *separator* parameters are
passed to :func:`urllib.parse.parse_qs` unchanged.
+ .. deprecated-removed:: 3.11 3.13
+ This function, like the rest of the :mod:`cgi` module, is deprecated.
+ It can be replaced by calling :func:`urllib.parse.parse_qs` directly
+ on the desired query string (except for ``multipart/form-data`` input,
+ which can be handled as described for :func:`parse_multipart`).
+
.. function:: parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator="&")
@@ -315,12 +329,31 @@ algorithms implemented in this module in other circumstances.
.. versionchanged:: 3.10
Added the *separator* parameter.
+ .. deprecated-removed:: 3.11 3.13
+ This function, like the rest of the :mod:`cgi` module, is deprecated.
+ It can be replaced with the functionality in the :mod:`email` package
+ (e.g. :class:`email.message.EmailMessage`/:class:`email.message.Message`)
+ which implements the same MIME RFCs, or with the
+ `multipart `__ PyPI project.
+
.. function:: parse_header(string)
Parse a MIME header (such as :mailheader:`Content-Type`) into a main value and a
dictionary of parameters.
+ .. deprecated-removed:: 3.11 3.13
+ This function, like the rest of the :mod:`cgi` module, is deprecated.
+ It can be replaced with the functionality in the :mod:`email` package,
+ which implements the same MIME RFCs.
+
+ For example, with :class:`email.message.EmailMessage`::
+
+ from email.message import EmailMessage
+ msg = EmailMessage()
+ msg['content-type'] = 'application/json; charset="utf8"'
+ main, params = msg.get_content_type(), msg['content-type'].params
+
.. function:: test()
diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst
index 349414610bd40a..7f00bcd55c1e53 100644
--- a/Doc/library/cgitb.rst
+++ b/Doc/library/cgitb.rst
@@ -16,8 +16,9 @@
single: exceptions; in CGI scripts
single: tracebacks; in CGI scripts
-.. deprecated:: 3.11
- The :mod:`cgitb` module is deprecated (see :pep:`594` for details).
+.. deprecated-removed:: 3.11 3.13
+ The :mod:`cgitb` module is deprecated
+ (see :pep:`PEP 594 <594#cgitb>` for details).
--------------
diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst
index 7999420f536d76..3b88e55b147882 100644
--- a/Doc/library/chunk.rst
+++ b/Doc/library/chunk.rst
@@ -17,8 +17,9 @@
single: Real Media File Format
single: RMFF
-.. deprecated:: 3.11
- The :mod:`chunk` module is deprecated (see :pep:`594` for details).
+.. deprecated-removed:: 3.11 3.13
+ The :mod:`chunk` module is deprecated
+ (see :pep:`PEP 594 <594#chunk>` for details).
--------------
diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst
index 28cd96b0e12da9..b17d58e1cc0ce1 100644
--- a/Doc/library/cmath.rst
+++ b/Doc/library/cmath.rst
@@ -15,11 +15,27 @@ the function is then applied to the result of the conversion.
.. note::
- On platforms with hardware and system-level support for signed
- zeros, functions involving branch cuts are continuous on *both*
- sides of the branch cut: the sign of the zero distinguishes one
- side of the branch cut from the other. On platforms that do not
- support signed zeros the continuity is as specified below.
+ For functions involving branch cuts, we have the problem of deciding how to
+ define those functions on the cut itself. Following Kahan's "Branch cuts for
+ complex elementary functions" paper, as well as Annex G of C99 and later C
+ standards, we use the sign of zero to distinguish one side of the branch cut
+ from the other: for a branch cut along (a portion of) the real axis we look
+ at the sign of the imaginary part, while for a branch cut along the
+ imaginary axis we look at the sign of the real part.
+
+ For example, the :func:`cmath.sqrt` function has a branch cut along the
+ negative real axis. An argument of ``complex(-2.0, -0.0)`` is treated as
+ though it lies *below* the branch cut, and so gives a result on the negative
+ imaginary axis::
+
+ >>> cmath.sqrt(complex(-2.0, -0.0))
+ -1.4142135623730951j
+
+ But an argument of ``complex(-2.0, 0.0)`` is treated as though it lies above
+ the branch cut::
+
+ >>> cmath.sqrt(complex(-2.0, 0.0))
+ 1.4142135623730951j
Conversions to and from polar coordinates
@@ -44,14 +60,11 @@ rectangular coordinates to polar coordinates and back.
.. function:: phase(x)
- Return the phase of *x* (also known as the *argument* of *x*), as a
- float. ``phase(x)`` is equivalent to ``math.atan2(x.imag,
- x.real)``. The result lies in the range [-\ *π*, *π*], and the branch
- cut for this operation lies along the negative real axis,
- continuous from above. On systems with support for signed zeros
- (which includes most systems in current use), this means that the
- sign of the result is the same as the sign of ``x.imag``, even when
- ``x.imag`` is zero::
+ Return the phase of *x* (also known as the *argument* of *x*), as a float.
+ ``phase(x)`` is equivalent to ``math.atan2(x.imag, x.real)``. The result
+ lies in the range [-\ *π*, *π*], and the branch cut for this operation lies
+ along the negative real axis. The sign of the result is the same as the
+ sign of ``x.imag``, even when ``x.imag`` is zero::
>>> phase(complex(-1.0, 0.0))
3.141592653589793
@@ -92,8 +105,8 @@ Power and logarithmic functions
.. function:: log(x[, base])
Returns the logarithm of *x* to the given *base*. If the *base* is not
- specified, returns the natural logarithm of *x*. There is one branch cut, from 0
- along the negative real axis to -∞, continuous from above.
+ specified, returns the natural logarithm of *x*. There is one branch cut,
+ from 0 along the negative real axis to -∞.
.. function:: log10(x)
@@ -112,9 +125,9 @@ Trigonometric functions
.. function:: acos(x)
- Return the arc cosine of *x*. There are two branch cuts: One extends right from
- 1 along the real axis to ∞, continuous from below. The other extends left from
- -1 along the real axis to -∞, continuous from above.
+ Return the arc cosine of *x*. There are two branch cuts: One extends right
+ from 1 along the real axis to ∞. The other extends left from -1 along the
+ real axis to -∞.
.. function:: asin(x)
@@ -125,9 +138,8 @@ Trigonometric functions
.. function:: atan(x)
Return the arc tangent of *x*. There are two branch cuts: One extends from
- ``1j`` along the imaginary axis to ``∞j``, continuous from the right. The
- other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous
- from the left.
+ ``1j`` along the imaginary axis to ``∞j``. The other extends from ``-1j``
+ along the imaginary axis to ``-∞j``.
.. function:: cos(x)
@@ -151,23 +163,21 @@ Hyperbolic functions
.. function:: acosh(x)
Return the inverse hyperbolic cosine of *x*. There is one branch cut,
- extending left from 1 along the real axis to -∞, continuous from above.
+ extending left from 1 along the real axis to -∞.
.. function:: asinh(x)
Return the inverse hyperbolic sine of *x*. There are two branch cuts:
- One extends from ``1j`` along the imaginary axis to ``∞j``,
- continuous from the right. The other extends from ``-1j`` along
- the imaginary axis to ``-∞j``, continuous from the left.
+ One extends from ``1j`` along the imaginary axis to ``∞j``. The other
+ extends from ``-1j`` along the imaginary axis to ``-∞j``.
.. function:: atanh(x)
Return the inverse hyperbolic tangent of *x*. There are two branch cuts: One
- extends from ``1`` along the real axis to ``∞``, continuous from below. The
- other extends from ``-1`` along the real axis to ``-∞``, continuous from
- above.
+ extends from ``1`` along the real axis to ``∞``. The other extends from
+ ``-1`` along the real axis to ``-∞``.
.. function:: cosh(x)
@@ -291,7 +301,7 @@ Constants
.. versionadded:: 3.6
-.. index:: module: math
+.. index:: pair: module; math
Note that the selection of functions is similar, but not identical, to that in
module :mod:`math`. The reason for having two modules is that some users aren't
diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst
index 26123fd0d0060c..8225236350d22e 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
@@ -189,7 +189,8 @@ wider range of codecs when working with binary files:
.. note::
- Underlying encoded files are always opened in binary mode.
+ If *encoding* is not ``None``, then the
+ underlying encoded files are always opened in binary mode.
No automatic conversion of ``'\n'`` is done on reading and writing.
The *mode* argument may be any binary mode acceptable to the built-in
:func:`open` function; the ``'b'`` is automatically added.
@@ -300,58 +301,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