diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml
index b5b2765e43844f..d3e842d9f31d01 100644
--- a/.azure-pipelines/ci.yml
+++ b/.azure-pipelines/ci.yml
@@ -1,4 +1,4 @@
-trigger: ['main', '3.12', '3.11', '3.10', '3.9', '3.8', '3.7']
+trigger: ['main', '3.13', '3.12', '3.11', '3.10', '3.9', '3.8']
jobs:
- job: Prebuild
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index c77bfb8d0d589a..50bab8acd323e1 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -141,6 +141,7 @@ Lib/ast.py @isidentical
**/*dataclasses* @ericvsmith
**/*idlelib* @terryjreedy
+/Doc/library/idle.rst @terryjreedy
**/*typing* @gvanrossum @JelleZijlstra @AlexWaygood
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 76ff0e438d7ab0..b10d3beaf53a67 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,8 +1,5 @@
name: Tests
-# gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because
-# it prevents to mark a job as mandatory. A PR cannot be merged if a job is
-# mandatory but not scheduled because of "paths-ignore".
on:
workflow_dispatch:
push:
@@ -31,70 +28,19 @@ concurrency:
jobs:
check_source:
- name: 'Check for source changes'
- runs-on: ubuntu-latest
- timeout-minutes: 10
- outputs:
- run-docs: ${{ steps.docs-changes.outputs.run-docs || false }}
- run_tests: ${{ steps.check.outputs.run_tests }}
- run_hypothesis: ${{ steps.check.outputs.run_hypothesis }}
- config_hash: ${{ steps.config_hash.outputs.hash }}
- steps:
- - uses: actions/checkout@v4
- - name: Check for source changes
- id: check
- run: |
- if [ -z "$GITHUB_BASE_REF" ]; then
- echo "run_tests=true" >> $GITHUB_OUTPUT
- else
- git fetch origin $GITHUB_BASE_REF --depth=1
- # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
- # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots),
- # but it requires to download more commits (this job uses
- # "git fetch --depth=1").
- #
- # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git
- # 2.26, but Git 2.28 is stricter and fails with "no merge base".
- #
- # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on
- # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF
- # 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|^\.pre-commit-config\.yaml$|\.ruff\.toml$)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true
- fi
-
- # Check if we should run hypothesis tests
- GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}}
- echo $GIT_BRANCH
- if $(echo "$GIT_BRANCH" | grep -q -w '3\.\(8\|9\|10\|11\)'); then
- echo "Branch too old for hypothesis tests"
- echo "run_hypothesis=false" >> $GITHUB_OUTPUT
- else
- echo "Run hypothesis tests"
- echo "run_hypothesis=true" >> $GITHUB_OUTPUT
- fi
- - name: Compute hash for config cache key
- id: config_hash
- run: |
- echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT
- - name: Get a list of the changed documentation-related files
- if: github.event_name == 'pull_request'
- id: changed-docs-files
- uses: Ana06/get-changed-files@v2.3.0
- with:
- filter: |
- Doc/**
- Misc/**
- .github/workflows/reusable-docs.yml
- format: csv # works for paths with spaces
- - name: Check for docs changes
- if: >-
- github.event_name == 'pull_request'
- && steps.changed-docs-files.outputs.added_modified_renamed != ''
- id: docs-changes
- run: |
- echo "run-docs=true" >> "${GITHUB_OUTPUT}"
+ name: Change detection
+ # To use boolean outputs from this job, parse them as JSON.
+ # Here's some examples:
+ #
+ # if: fromJSON(needs.check_source.outputs.run-docs)
+ #
+ # ${{
+ # fromJSON(needs.check_source.outputs.run_tests)
+ # && 'truthy-branch'
+ # || 'falsy-branch'
+ # }}
+ #
+ uses: ./.github/workflows/reusable-change-detection.yml
check-docs:
name: Docs
@@ -216,34 +162,89 @@ jobs:
run: make check-c-globals
build_windows:
- name: 'Windows'
+ name: >-
+ Windows
+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
needs: check_source
- if: needs.check_source.outputs.run_tests == 'true'
+ if: fromJSON(needs.check_source.outputs.run_tests)
+ strategy:
+ matrix:
+ arch:
+ - Win32
+ - x64
+ - arm64
+ free-threading:
+ - false
+ # - true
uses: ./.github/workflows/reusable-windows.yml
+ with:
+ arch: ${{ matrix.arch }}
+ free-threading: ${{ matrix.free-threading }}
+
+ build_windows_msi:
+ name: >- # ${{ '' } is a hack to nest jobs under the same sidebar category
+ Windows MSI${{ '' }}
+ needs: check_source
+ if: fromJSON(needs.check_source.outputs.run-win-msi)
+ strategy:
+ matrix:
+ arch:
+ - x86
+ - x64
+ - arm64
+ uses: ./.github/workflows/reusable-windows-msi.yml
+ with:
+ arch: ${{ matrix.arch }}
build_macos:
- name: 'macOS'
+ name: >-
+ macOS
+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
+ strategy:
+ fail-fast: false
+ matrix:
+ # Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
+ # macOS 13 only runs tests against the GIL-enabled CPython.
+ # Cirrus used for upstream, macos-14 for forks.
+ os:
+ - ghcr.io/cirruslabs/macos-runner:sonoma
+ - macos-14
+ - macos-13
+ is-fork: # only used for the exclusion trick
+ - ${{ github.repository_owner != 'python' }}
+ free-threading:
+ - false
+ # - true
+ exclude:
+ - os: ghcr.io/cirruslabs/macos-runner:sonoma
+ is-fork: true
+ - os: macos-14
+ is-fork: false
+ - os: macos-13
+ free-threading: true
uses: ./.github/workflows/reusable-macos.yml
with:
config_hash: ${{ needs.check_source.outputs.config_hash }}
- # Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
- # Cirrus used for upstream, macos-14 for forks.
- os-matrix: '["ghcr.io/cirruslabs/macos-runner:sonoma", "macos-14", "macos-13"]'
+ free-threading: ${{ matrix.free-threading }}
+ os: ${{ matrix.os }}
build_ubuntu:
- name: 'Ubuntu'
+ name: >-
+ Ubuntu
+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
+ strategy:
+ matrix:
+ free-threading:
+ - false
+ # - true
uses: ./.github/workflows/reusable-ubuntu.yml
with:
config_hash: ${{ needs.check_source.outputs.config_hash }}
- options: |
- ../cpython-ro-srcdir/configure \
- --config-cache \
- --with-pydebug \
- --with-openssl=$OPENSSL_DIR
+ free-threading: ${{ matrix.free-threading }}
build_ubuntu_ssltests:
name: 'Ubuntu SSL tests with OpenSSL'
@@ -388,7 +389,7 @@ jobs:
path: ./hypothesis
key: hypothesis-database-${{ github.head_ref || github.run_id }}
restore-keys: |
- - hypothesis-database-
+ hypothesis-database-
- name: "Run tests"
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: |
@@ -495,6 +496,7 @@ jobs:
- build_ubuntu
- build_ubuntu_ssltests
- build_windows
+ - build_windows_msi
- test_hypothesis
- build_asan
- build_tsan
@@ -508,6 +510,7 @@ jobs:
allowed-failures: >-
build_macos,
build_ubuntu_ssltests,
+ build_windows_msi,
test_hypothesis,
allowed-skips: >-
${{
diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml
deleted file mode 100644
index 29282dffa37ec0..00000000000000
--- a/.github/workflows/build_msi.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: TestsMSI
-
-on:
- workflow_dispatch:
- push:
- branches:
- - 'main'
- - '3.*'
- paths:
- - 'Tools/msi/**'
- - '.github/workflows/build_msi.yml'
- pull_request:
- branches:
- - 'main'
- - '3.*'
- paths:
- - 'Tools/msi/**'
- - '.github/workflows/build_msi.yml'
-
-permissions:
- contents: read
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
- cancel-in-progress: true
-
-jobs:
- build:
- name: Windows Installer
- runs-on: windows-latest
- timeout-minutes: 60
- strategy:
- matrix:
- type: [x86, x64, arm64]
- steps:
- - uses: actions/checkout@v4
- - name: Build CPython installer
- run: .\Tools\msi\build.bat --doc -${{ matrix.type }}
diff --git a/.github/workflows/reusable-change-detection.yml b/.github/workflows/reusable-change-detection.yml
new file mode 100644
index 00000000000000..25c789d335efc8
--- /dev/null
+++ b/.github/workflows/reusable-change-detection.yml
@@ -0,0 +1,150 @@
+---
+
+name: Change detection
+
+on: # yamllint disable-line rule:truthy
+ workflow_call:
+ outputs:
+ # Some of the referenced steps set outputs conditionally and there may be
+ # cases when referencing them evaluates to empty strings. It is nice to
+ # work with proper booleans so they have to be evaluated through JSON
+ # conversion in the expressions. However, empty strings used like that
+ # may trigger all sorts of undefined and hard-to-debug behaviors in
+ # GitHub Actions CI/CD. To help with this, all of the outputs set here
+ # that are meant to be used as boolean flags (and not arbitrary strings),
+ # MUST have fallbacks with default values set. A common pattern would be
+ # to add ` || false` to all such expressions here, in the output
+ # definitions. They can then later be safely used through the following
+ # idiom in job conditionals and other expressions. Here's some examples:
+ #
+ # if: fromJSON(needs.change-detection.outputs.run-docs)
+ #
+ # ${{
+ # fromJSON(needs.change-detection.outputs.run-tests)
+ # && 'truthy-branch'
+ # || 'falsy-branch'
+ # }}
+ #
+ config_hash:
+ description: Config hash value for use in cache keys
+ value: ${{ jobs.compute-changes.outputs.config-hash }} # str
+ run-docs:
+ description: Whether to build the docs
+ value: ${{ jobs.compute-changes.outputs.run-docs || false }} # bool
+ run_tests:
+ description: Whether to run the regular tests
+ value: ${{ jobs.compute-changes.outputs.run-tests || false }} # bool
+ run-win-msi:
+ description: Whether to run the MSI installer smoke tests
+ value: >- # bool
+ ${{ jobs.compute-changes.outputs.run-win-msi || false }}
+ run_hypothesis:
+ description: Whether to run the Hypothesis tests
+ value: >- # bool
+ ${{ jobs.compute-changes.outputs.run-hypothesis || false }}
+ run_cifuzz:
+ description: Whether to run the CIFuzz job
+ value: >- # bool
+ ${{ jobs.compute-changes.outputs.run-cifuzz || false }}
+
+jobs:
+ compute-changes:
+ name: Compute changed files
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ outputs:
+ config-hash: ${{ steps.config-hash.outputs.hash }}
+ run-cifuzz: ${{ steps.check.outputs.run-cifuzz }}
+ run-docs: ${{ steps.docs-changes.outputs.run-docs }}
+ run-hypothesis: ${{ steps.check.outputs.run-hypothesis }}
+ run-tests: ${{ steps.check.outputs.run-tests }}
+ run-win-msi: ${{ steps.win-msi-changes.outputs.run-win-msi }}
+ steps:
+ - run: >-
+ echo '${{ github.event_name }}'
+ - uses: actions/checkout@v4
+ - name: Check for source changes
+ id: check
+ run: |
+ if [ -z "$GITHUB_BASE_REF" ]; then
+ echo "run-tests=true" >> $GITHUB_OUTPUT
+ else
+ git fetch origin $GITHUB_BASE_REF --depth=1
+ # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
+ # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots),
+ # but it requires to download more commits (this job uses
+ # "git fetch --depth=1").
+ #
+ # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git
+ # 2.26, but Git 2.28 is stricter and fails with "no merge base".
+ #
+ # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on
+ # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF
+ # 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|^\.pre-commit-config\.yaml$|\.ruff\.toml$|\.md$|mypy\.ini$)' && echo "run-tests=true" >> $GITHUB_OUTPUT || true
+ fi
+
+ # Check if we should run hypothesis tests
+ GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}}
+ echo $GIT_BRANCH
+ if $(echo "$GIT_BRANCH" | grep -q -w '3\.\(8\|9\|10\|11\)'); then
+ echo "Branch too old for hypothesis tests"
+ echo "run-hypothesis=false" >> $GITHUB_OUTPUT
+ else
+ echo "Run hypothesis tests"
+ echo "run-hypothesis=true" >> $GITHUB_OUTPUT
+ fi
+
+ # oss-fuzz maintains a configuration for fuzzing the main branch of
+ # CPython, so CIFuzz should be run only for code that is likely to be
+ # merged into the main branch; compatibility with older branches may
+ # be broken.
+ FUZZ_RELEVANT_FILES='(\.c$|\.h$|\.cpp$|^configure$|^\.github/workflows/build\.yml$|^Modules/_xxtestfuzz)'
+ if [ "$GITHUB_BASE_REF" = "main" ] && [ "$(git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE $FUZZ_RELEVANT_FILES; echo $?)" -eq 0 ]; then
+ # The tests are pretty slow so they are executed only for PRs
+ # changing relevant files.
+ echo "Run CIFuzz tests"
+ echo "run-cifuzz=true" >> $GITHUB_OUTPUT
+ else
+ echo "Branch too old for CIFuzz tests; or no C files were changed"
+ echo "run-cifuzz=false" >> $GITHUB_OUTPUT
+ fi
+ - name: Compute hash for config cache key
+ id: config-hash
+ run: |
+ echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT
+ - name: Get a list of the changed documentation-related files
+ if: github.event_name == 'pull_request'
+ id: changed-docs-files
+ uses: Ana06/get-changed-files@v2.3.0
+ with:
+ filter: |
+ Doc/**
+ Misc/**
+ .github/workflows/reusable-docs.yml
+ format: csv # works for paths with spaces
+ - name: Check for docs changes
+ if: >-
+ github.event_name == 'pull_request'
+ && steps.changed-docs-files.outputs.added_modified_renamed != ''
+ id: docs-changes
+ run: |
+ echo "run-docs=true" >> "${GITHUB_OUTPUT}"
+ - name: Get a list of the MSI installer-related files
+ id: changed-win-msi-files
+ uses: Ana06/get-changed-files@v2.3.0
+ with:
+ filter: |
+ Tools/msi/**
+ .github/workflows/reusable-windows-msi.yml
+ format: csv # works for paths with spaces
+ - name: Check for changes in MSI installer-related files
+ if: >-
+ steps.changed-win-msi-files.outputs.added_modified_renamed != ''
+ id: win-msi-changes
+ run: |
+ echo "run-win-msi=true" >> "${GITHUB_OUTPUT}"
+
+...
diff --git a/.github/workflows/reusable-macos.yml b/.github/workflows/reusable-macos.yml
index 9c197aa732fcc5..47f5ee2fb63888 100644
--- a/.github/workflows/reusable-macos.yml
+++ b/.github/workflows/reusable-macos.yml
@@ -8,13 +8,14 @@ on:
required: false
type: boolean
default: false
- os-matrix:
- required: false
+ os:
+ description: OS to run the job
+ required: true
type: string
jobs:
build_macos:
- name: build and test (${{ matrix.os }})
+ name: build and test (${{ inputs.os }})
timeout-minutes: 60
env:
HOMEBREW_NO_ANALYTICS: 1
@@ -22,18 +23,7 @@ jobs:
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
PYTHONSTRICTEXTENSIONBUILD: 1
- strategy:
- fail-fast: false
- matrix:
- os: ${{fromJson(inputs.os-matrix)}}
- is-fork:
- - ${{ github.repository_owner != 'python' }}
- exclude:
- - os: "ghcr.io/cirruslabs/macos-runner:sonoma"
- is-fork: true
- - os: "macos-14"
- is-fork: false
- runs-on: ${{ matrix.os }}
+ runs-on: ${{ inputs.os }}
steps:
- uses: actions/checkout@v4
- name: Runner image version
@@ -42,7 +32,7 @@ jobs:
uses: actions/cache@v4
with:
path: config.cache
- key: ${{ github.job }}-${{ matrix.os }}-${{ env.IMAGE_VERSION }}-${{ inputs.config_hash }}
+ key: ${{ github.job }}-${{ inputs.os }}-${{ env.IMAGE_VERSION }}-${{ inputs.config_hash }}
- name: Install Homebrew dependencies
run: brew install pkg-config openssl@3.0 xz gdbm tcl-tk
- name: Configure CPython
diff --git a/.github/workflows/reusable-ubuntu.yml b/.github/workflows/reusable-ubuntu.yml
index 0dbfcabaa8755e..dd47a380da1e77 100644
--- a/.github/workflows/reusable-ubuntu.yml
+++ b/.github/workflows/reusable-ubuntu.yml
@@ -4,9 +4,11 @@ on:
config_hash:
required: true
type: string
- options:
- required: true
- type: string
+ free-threading:
+ description: Whether to use free-threaded mode
+ required: false
+ type: boolean
+ default: false
jobs:
build_ubuntu_reusable:
@@ -61,7 +63,12 @@ jobs:
key: ${{ github.job }}-${{ runner.os }}-${{ env.IMAGE_VERSION }}-${{ inputs.config_hash }}
- name: Configure CPython out-of-tree
working-directory: ${{ env.CPYTHON_BUILDDIR }}
- run: ${{ inputs.options }}
+ run: >-
+ ../cpython-ro-srcdir/configure
+ --config-cache
+ --with-pydebug
+ --with-openssl=$OPENSSL_DIR
+ ${{ fromJSON(inputs.free-threading) && '--disable-gil' || '' }}
- name: Build CPython out-of-tree
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: make -j4
diff --git a/.github/workflows/reusable-windows-msi.yml b/.github/workflows/reusable-windows-msi.yml
new file mode 100644
index 00000000000000..fc34ab7c3eb1f2
--- /dev/null
+++ b/.github/workflows/reusable-windows-msi.yml
@@ -0,0 +1,24 @@
+name: TestsMSI
+
+on:
+ workflow_call:
+ inputs:
+ arch:
+ description: CPU architecture
+ required: true
+ type: string
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: installer for ${{ inputs.arch }}
+ runs-on: windows-latest
+ timeout-minutes: 60
+ env:
+ IncludeFreethreaded: true
+ steps:
+ - uses: actions/checkout@v4
+ - name: Build CPython installer
+ run: .\Tools\msi\build.bat --doc -${{ inputs.arch }}
diff --git a/.github/workflows/reusable-windows.yml b/.github/workflows/reusable-windows.yml
index 41f2c2b0c2cd25..8b886056fe56b8 100644
--- a/.github/workflows/reusable-windows.yml
+++ b/.github/workflows/reusable-windows.yml
@@ -1,53 +1,45 @@
on:
workflow_call:
inputs:
+ arch:
+ description: CPU architecture
+ required: true
+ type: string
free-threading:
+ description: Whether to compile CPython in free-threading mode
required: false
type: boolean
default: false
-jobs:
- build_win32:
- name: 'build and test (x86)'
- runs-on: windows-latest
- timeout-minutes: 60
- env:
- IncludeUwp: 'true'
- steps:
- - uses: actions/checkout@v4
- - name: Build CPython
- run: .\PCbuild\build.bat -e -d -p Win32 ${{ inputs.free-threading && '--disable-gil' || '' }}
- - name: Display build info
- run: .\python.bat -m test.pythoninfo
- - name: Tests
- run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
+env:
+ IncludeUwp: >-
+ true
- build_win_amd64:
- name: 'build and test (x64)'
+jobs:
+ build:
+ name: >-
+ build${{ inputs.arch != 'arm64' && ' and test' || '' }}
+ (${{ inputs.arch }})
runs-on: windows-latest
timeout-minutes: 60
- env:
- IncludeUwp: 'true'
steps:
- uses: actions/checkout@v4
- name: Register MSVC problem matcher
+ if: inputs.arch != 'Win32'
run: echo "::add-matcher::.github/problem-matchers/msvc.json"
- name: Build CPython
- run: .\PCbuild\build.bat -e -d -p x64 ${{ inputs.free-threading && '--disable-gil' || '' }}
+ run: >-
+ .\PCbuild\build.bat
+ -e -d
+ -p ${{ inputs.arch }}
+ ${{ fromJSON(inputs.free-threading) && '--disable-gil' || '' }}
- name: Display build info
+ if: inputs.arch != 'arm64'
run: .\python.bat -m test.pythoninfo
- name: Tests
- run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
-
- build_win_arm64:
- name: 'build (arm64)'
- runs-on: windows-latest
- timeout-minutes: 60
- env:
- IncludeUwp: 'true'
- steps:
- - uses: actions/checkout@v4
- - name: Register MSVC problem matcher
- run: echo "::add-matcher::.github/problem-matchers/msvc.json"
- - name: Build CPython
- run: .\PCbuild\build.bat -e -d -p arm64 ${{ inputs.free-threading && '--disable-gil' || '' }}
+ if: inputs.arch != 'arm64'
+ run: >-
+ .\PCbuild\rt.bat
+ -p ${{ inputs.arch }}
+ -d -q -uall -u-cpu -rwW
+ --slowest --timeout=1200 -j0
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 663a11897d98e2..c64ca3186775f2 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,13 +3,21 @@ repos:
rev: v0.3.4
hooks:
- id: ruff
- name: Run Ruff on Lib/test/
+ name: Run Ruff (lint) on Doc/
+ args: [--exit-non-zero-on-fix]
+ files: ^Doc/
+ - id: ruff
+ name: Run Ruff (lint) on Lib/test/
args: [--exit-non-zero-on-fix]
files: ^Lib/test/
- id: ruff
- name: Run Ruff on Argument Clinic
+ name: Run Ruff (lint) on Argument Clinic
args: [--exit-non-zero-on-fix, --config=Tools/clinic/.ruff.toml]
files: ^Tools/clinic/|Lib/test/test_clinic.py
+ - id: ruff-format
+ name: Run Ruff (format) on Doc/
+ args: [--check]
+ files: ^Doc/
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 898a9ae89dbb92..250d7ea02338d8 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -8,11 +8,14 @@ sphinx:
configuration: Doc/conf.py
build:
- os: ubuntu-22.04
+ os: ubuntu-24.04
tools:
python: "3"
commands:
+ - asdf plugin add uv
+ - asdf install uv latest
+ - asdf global uv latest
- make -C Doc venv html
- mkdir _readthedocs
- mv Doc/build/html _readthedocs/html
diff --git a/Doc/.ruff.toml b/Doc/.ruff.toml
new file mode 100644
index 00000000000000..111ce03b91df38
--- /dev/null
+++ b/Doc/.ruff.toml
@@ -0,0 +1,42 @@
+target-version = "py312" # Align with the version in oldest_supported_sphinx
+fix = true
+output-format = "full"
+line-length = 79
+extend-exclude = [
+ "includes/*",
+ # Temporary exclusions:
+ "tools/extensions/pyspecific.py",
+]
+
+[lint]
+preview = true
+select = [
+ "C4", # flake8-comprehensions
+ "B", # flake8-bugbear
+ "E", # pycodestyle
+ "F", # pyflakes
+ "FA", # flake8-future-annotations
+ "FLY", # flynt
+ "FURB", # refurb
+ "G", # flake8-logging-format
+ "I", # isort
+ "LOG", # flake8-logging
+ "N", # pep8-naming
+ "PERF", # perflint
+ "PGH", # pygrep-hooks
+ "PT", # flake8-pytest-style
+ "TCH", # flake8-type-checking
+ "UP", # pyupgrade
+ "W", # pycodestyle
+]
+ignore = [
+ "E501", # Ignore line length errors (we use auto-formatting)
+]
+
+[format]
+preview = true
+quote-style = "preserve"
+docstring-code-format = true
+exclude = [
+ "tools/extensions/lexers/*",
+]
diff --git a/Doc/Makefile b/Doc/Makefile
index 1cbfc722b010f5..b2ee3fe7d28ed0 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -6,6 +6,7 @@
# You can set these variables from the command line.
PYTHON = python3
VENVDIR = ./venv
+UV = uv
SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-build
BLURB = PATH=$(VENVDIR)/bin:$$PATH blurb
JOBS = auto
@@ -150,14 +151,10 @@ gettext: build
htmlview: html
$(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/html/index.html'))"
-.PHONY: ensure-sphinx-autobuild
-ensure-sphinx-autobuild: venv
- $(VENVDIR)/bin/sphinx-autobuild --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install sphinx-autobuild
-
.PHONY: htmllive
htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild
htmllive: SPHINXOPTS = --re-ignore="/venv/" --open-browser --delay 0
-htmllive: ensure-sphinx-autobuild html
+htmllive: _ensure-sphinx-autobuild html
.PHONY: clean
clean: clean-venv
@@ -174,9 +171,14 @@ venv:
echo "To recreate it, remove it first with \`make clean-venv'."; \
else \
echo "Creating venv in $(VENVDIR)"; \
- $(PYTHON) -m venv $(VENVDIR); \
- $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \
- $(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \
+ if $(UV) --version >/dev/null 2>&1; then \
+ $(UV) venv $(VENVDIR); \
+ VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \
+ else \
+ $(PYTHON) -m venv $(VENVDIR); \
+ $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \
+ $(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \
+ fi; \
echo "The venv has been created in the $(VENVDIR) directory"; \
fi
@@ -235,9 +237,24 @@ dist:
rm -r dist/python-$(DISTVERSION)-docs-texinfo
rm dist/python-$(DISTVERSION)-docs-texinfo.tar
+.PHONY: _ensure-package
+_ensure-package: venv
+ if $(UV) --version >/dev/null 2>&1; then \
+ VIRTUAL_ENV=$(VENVDIR) $(UV) pip install $(PACKAGE); \
+ else \
+ $(VENVDIR)/bin/python3 -m pip install $(PACKAGE); \
+ fi
+
+.PHONY: _ensure-pre-commit
+_ensure-pre-commit:
+ make _ensure-package PACKAGE=pre-commit
+
+.PHONY: _ensure-sphinx-autobuild
+_ensure-sphinx-autobuild:
+ make _ensure-package PACKAGE=sphinx-autobuild
+
.PHONY: check
-check: venv
- $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit
+check: _ensure-pre-commit
$(VENVDIR)/bin/python3 -m pre_commit run --all-files
.PHONY: serve
diff --git a/Doc/README.rst b/Doc/README.rst
index a3bb5fa5445c23..efcee0db428908 100644
--- a/Doc/README.rst
+++ b/Doc/README.rst
@@ -28,7 +28,7 @@ install the tools into there.
Using make
----------
-To get started on UNIX, you can create a virtual environment and build
+To get started on Unix, you can create a virtual environment and build
documentation with the commands::
make venv
@@ -40,13 +40,13 @@ 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 ``sphinx-build`` 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).
-On Windows, we try to emulate the Makefile as closely as possible with a
+On Windows, we try to emulate the ``Makefile`` as closely as possible with a
``make.bat`` file. If you need to specify the Python interpreter to use,
-set the PYTHON environment variable.
+set the ``PYTHON`` environment variable.
Available make targets are:
@@ -62,15 +62,19 @@ Available make targets are:
* "htmlview", which re-uses the "html" builder, but then opens the main page
in your default web browser.
+* "htmllive", which re-uses the "html" builder, rebuilds the docs,
+ starts a local server, and automatically reloads the page in your browser
+ when you make changes to reST files (Unix only).
+
* "htmlhelp", which builds HTML files and a HTML Help project file usable to
convert them into a single Compiled HTML (.chm) file -- these are popular
under Microsoft Windows, but very handy on every platform.
To create the CHM file, you need to run the Microsoft HTML Help Workshop
- over the generated project (.hhp) file. The make.bat script does this for
+ over the generated project (.hhp) file. The ``make.bat`` script does this for
you on Windows.
-* "latex", which builds LaTeX source files as input to "pdflatex" to produce
+* "latex", which builds LaTeX source files as input to ``pdflatex`` to produce
PDF documents.
* "text", which builds a plain text file for each source file.
@@ -95,8 +99,6 @@ Available make targets are:
* "check", which checks for frequent markup errors.
-* "serve", which serves the build/html directory on port 8000.
-
* "dist", (Unix only) which creates distributable archives of HTML, text,
PDF, and EPUB builds.
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 657b10d3e0ac48..b8af24f53c3b7c 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -280,10 +280,10 @@ Numbers
length 1, to a C :c:expr:`int`.
``f`` (:class:`float`) [float]
- Convert a Python floating point number to a C :c:expr:`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:expr:`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.
@@ -607,10 +607,10 @@ Building values
object of length 1.
``d`` (:class:`float`) [double]
- Convert a C :c:expr:`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:expr:`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.
diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst
index 456f7d89bca03c..9045689a6be567 100644
--- a/Doc/c-api/bytearray.rst
+++ b/Doc/c-api/bytearray.rst
@@ -42,17 +42,22 @@ Direct API functions
Return a new bytearray object from any object, *o*, that implements the
:ref:`buffer protocol `.
+ On failure, return ``NULL`` with an exception set.
+
.. c:function:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len)
- Create a new bytearray object from *string* and its length, *len*. On
- failure, ``NULL`` is returned.
+ Create a new bytearray object from *string* and its length, *len*.
+
+ On failure, return ``NULL`` with an exception set.
.. c:function:: PyObject* PyByteArray_Concat(PyObject *a, PyObject *b)
Concat bytearrays *a* and *b* and return a new bytearray with the result.
+ On failure, return ``NULL`` with an exception set.
+
.. c:function:: Py_ssize_t PyByteArray_Size(PyObject *bytearray)
diff --git a/Doc/c-api/cell.rst b/Doc/c-api/cell.rst
index f8cd0344fdd1c0..61eb994c370946 100644
--- a/Doc/c-api/cell.rst
+++ b/Doc/c-api/cell.rst
@@ -39,7 +39,8 @@ Cell objects are not likely to be useful elsewhere.
.. c:function:: PyObject* PyCell_Get(PyObject *cell)
- Return the contents of the cell *cell*.
+ Return the contents of the cell *cell*, which can be ``NULL``.
+ If *cell* is not a cell object, returns ``NULL`` with an exception set.
.. c:function:: PyObject* PyCell_GET(PyObject *cell)
@@ -52,8 +53,10 @@ Cell objects are not likely to be useful elsewhere.
Set the contents of the cell object *cell* to *value*. This releases the
reference to any current content of the cell. *value* may be ``NULL``. *cell*
- must be non-``NULL``; if it is not a cell object, ``-1`` will be returned. On
- success, ``0`` will be returned.
+ must be non-``NULL``.
+
+ On success, return ``0``.
+ If *cell* is not a cell object, set an exception and return ``-1``.
.. c:function:: void PyCell_SET(PyObject *cell, PyObject *value)
diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst
index e3fd001c599c80..77cb67d8de2b4c 100644
--- a/Doc/c-api/complex.rst
+++ b/Doc/c-api/complex.rst
@@ -25,12 +25,16 @@ pointers. This is consistent throughout the API.
The C structure which corresponds to the value portion of a Python complex
number object. Most of the functions for dealing with complex number objects
- use structures of this type as input or output values, as appropriate. It is
- defined as::
+ use structures of this type as input or output values, as appropriate.
+
+ .. c:member:: double real
+ double imag
+
+ The structure is defined as::
typedef struct {
- double real;
- double imag;
+ double real;
+ double imag;
} Py_complex;
@@ -106,17 +110,22 @@ Complex Numbers as Python Objects
.. c:function:: PyObject* PyComplex_FromCComplex(Py_complex v)
Create a new Python complex number object from a C :c:type:`Py_complex` value.
+ Return ``NULL`` with an exception set on error.
.. c:function:: PyObject* PyComplex_FromDoubles(double real, double imag)
Return a new :c:type:`PyComplexObject` object from *real* and *imag*.
+ Return ``NULL`` with an exception set on error.
.. c:function:: double PyComplex_RealAsDouble(PyObject *op)
Return the real part of *op* as a C :c:expr:`double`.
+ Upon failure, this method returns ``-1.0`` with an exception set, so one
+ should call :c:func:`PyErr_Occurred` to check for errors.
+
.. c:function:: double PyComplex_ImagAsDouble(PyObject *op)
@@ -131,8 +140,11 @@ Complex Numbers as Python Objects
method, this method will first be called to convert *op* to a Python complex
number object. If :meth:`!__complex__` is not defined then it falls back to
:meth:`~object.__float__`. If :meth:`!__float__` is not defined then it falls back
- to :meth:`~object.__index__`. Upon failure, this method returns ``-1.0`` as a real
- value.
+ to :meth:`~object.__index__`.
+
+ Upon failure, this method returns :c:type:`Py_complex`
+ with :c:member:`~Py_complex.real` set to ``-1.0`` and with an exception set, so one
+ should call :c:func:`PyErr_Occurred` to check for errors.
.. versionchanged:: 3.8
Use :meth:`~object.__index__` if available.
diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst
index 4f6ac0d8175c6b..1da37a5bcaeef9 100644
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -2,20 +2,20 @@
.. _floatobjects:
-Floating Point Objects
+Floating-Point Objects
======================
-.. index:: pair: object; floating point
+.. index:: pair: object; floating-point
.. c:type:: PyFloatObject
- This subtype of :c:type:`PyObject` represents a Python floating point object.
+ This subtype of :c:type:`PyObject` represents a Python floating-point object.
.. c:var:: PyTypeObject PyFloat_Type
- This instance of :c:type:`PyTypeObject` represents the Python floating point
+ This instance of :c:type:`PyTypeObject` represents the Python floating-point
type. This is the same object as :class:`float` in the Python layer.
@@ -45,7 +45,7 @@ Floating Point Objects
.. c:function:: double PyFloat_AsDouble(PyObject *pyfloat)
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:`~object.__float__`
+ *pyfloat* is not a Python floating-point object but has a :meth:`~object.__float__`
method, this method will first be called to convert *pyfloat* into a float.
If :meth:`!__float__` is not defined then it falls back to :meth:`~object.__index__`.
This method returns ``-1.0`` upon failure, so one should call
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index a51f1da6b66104..8b7b28ae319200 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -388,9 +388,16 @@ Initializing and finalizing the interpreter
:c:func:`Py_NewInterpreter` below) that were created and not yet destroyed since
the last call to :c:func:`Py_Initialize`. Ideally, this frees all memory
allocated by the Python interpreter. This is a no-op when called for a second
- time (without calling :c:func:`Py_Initialize` again first). Normally the
- return value is ``0``. If there were errors during finalization
- (flushing buffered data), ``-1`` is returned.
+ time (without calling :c:func:`Py_Initialize` again first).
+
+ Since this is the reverse of :c:func:`Py_Initialize`, it should be called
+ in the same thread with the same interpreter active. That means
+ the main thread and the main interpreter.
+ This should never be called while :c:func:`Py_RunMain` is running.
+
+ Normally the return value is ``0``.
+ If there were errors during finalization (flushing buffered data),
+ ``-1`` is returned.
This function is provided for a number of reasons. An embedding application
might want to restart Python without having to restart the application itself.
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index 7c5465b5bfa204..26252506868507 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -499,7 +499,7 @@ PyConfig
The :c:func:`PyConfig_Read` function only parses
:c:member:`PyConfig.argv` arguments once: :c:member:`PyConfig.parse_argv`
is set to ``2`` after arguments are parsed. Since Python arguments are
- strippped from :c:member:`PyConfig.argv`, parsing arguments twice would
+ stripped from :c:member:`PyConfig.argv`, parsing arguments twice would
parse the application options as Python options.
:ref:`Preinitialize Python ` if needed.
@@ -1000,7 +1000,7 @@ PyConfig
The :c:func:`PyConfig_Read` function only parses
:c:member:`PyConfig.argv` arguments once: :c:member:`PyConfig.parse_argv`
is set to ``2`` after arguments are parsed. Since Python arguments are
- strippped from :c:member:`PyConfig.argv`, parsing arguments twice would
+ stripped from :c:member:`PyConfig.argv`, parsing arguments twice would
parse the application options as Python options.
Default: ``1`` in Python mode, ``0`` in isolated mode.
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 76ac80322f8f40..af86810c6b166b 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -324,6 +324,17 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
Returns ``NULL`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+.. c:function:: PyObject* PyLong_GetInfo(void)
+
+ On success, return a read only :term:`named tuple`, that holds
+ information about Python's internal representation of integers.
+ See :data:`sys.int_info` for description of individual fields.
+
+ On failure, return ``NULL`` with an exception set.
+
+ .. versionadded:: 3.1
+
+
.. c:function:: int PyUnstable_Long_IsCompact(const PyLongObject* op)
Return 1 if *op* is compact, 0 otherwise.
diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst
index 489f1580a414b2..b9085ad3ec361d 100644
--- a/Doc/c-api/marshal.rst
+++ b/Doc/c-api/marshal.rst
@@ -15,7 +15,7 @@ Numeric values are stored with the least significant byte first.
The module supports two versions of the data format: version 0 is the
historical version, version 1 shares interned strings in the file, and upon
-unmarshalling. Version 2 uses a binary format for floating point numbers.
+unmarshalling. Version 2 uses a binary format for floating-point numbers.
``Py_MARSHAL_VERSION`` indicates the current file format (currently 2).
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index f941f0c7d42b2b..9340a9426567dc 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -43,6 +43,8 @@ Module Objects
to ``None``); the caller is responsible for providing a :attr:`__file__`
attribute.
+ Return ``NULL`` with an exception set on error.
+
.. versionadded:: 3.3
.. versionchanged:: 3.4
@@ -265,6 +267,8 @@ of the following two module creation functions:
API version *module_api_version*. If that version does not match the version
of the running interpreter, a :exc:`RuntimeWarning` is emitted.
+ Return ``NULL`` with an exception set on error.
+
.. note::
Most uses of this function should be using :c:func:`PyModule_Create`
@@ -338,7 +342,8 @@ The available slot types are:
The *value* pointer of this slot must point to a function of the signature:
.. c:function:: PyObject* create_module(PyObject *spec, PyModuleDef *def)
- :noindex:
+ :no-index-entry:
+ :no-contents-entry:
The function receives a :py:class:`~importlib.machinery.ModuleSpec`
instance, as defined in :PEP:`451`, and the module definition.
@@ -373,7 +378,8 @@ The available slot types are:
The signature of the function is:
.. c:function:: int exec_module(PyObject* module)
- :noindex:
+ :no-index-entry:
+ :no-contents-entry:
If multiple ``Py_mod_exec`` slots are specified, they are processed in the
order they appear in the *m_slots* array.
@@ -436,6 +442,8 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and
If that version does not match the version of the running interpreter,
a :exc:`RuntimeWarning` is emitted.
+ Return ``NULL`` with an exception set on error.
+
.. note::
Most uses of this function should be using :c:func:`PyModule_FromDefAndSpec`
@@ -486,7 +494,7 @@ state:
On success, return ``0``. On error, raise an exception and return ``-1``.
- Return ``NULL`` if *value* is ``NULL``. It must be called with an exception
+ Return ``-1`` if *value* is ``NULL``. It must be called with an exception
raised in this case.
Example usage::
@@ -579,15 +587,16 @@ state:
.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
Add an integer constant to *module* as *name*. This convenience function can be
- used from the module's initialization function. Return ``-1`` on error, ``0`` on
- success.
+ used from the module's initialization function.
+ Return ``-1`` with an exception set on error, ``0`` on success.
.. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)
Add a string constant to *module* as *name*. This convenience function can be
used from the module's initialization function. The string *value* must be
- ``NULL``-terminated. Return ``-1`` on error, ``0`` on success.
+ ``NULL``-terminated.
+ Return ``-1`` with an exception set on error, ``0`` on success.
.. c:macro:: PyModule_AddIntMacro(module, macro)
@@ -595,7 +604,7 @@ state:
Add an int constant to *module*. The name and the value are taken from
*macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int
constant *AF_INET* with the value of *AF_INET* to *module*.
- Return ``-1`` on error, ``0`` on success.
+ Return ``-1`` with an exception set on error, ``0`` on success.
.. c:macro:: PyModule_AddStringMacro(module, macro)
@@ -608,7 +617,7 @@ state:
The type object is finalized by calling internally :c:func:`PyType_Ready`.
The name of the type object is taken from the last component of
:c:member:`~PyTypeObject.tp_name` after dot.
- Return ``-1`` on error, ``0`` on success.
+ Return ``-1`` with an exception set on error, ``0`` on success.
.. versionadded:: 3.9
@@ -647,14 +656,14 @@ since multiple such modules can be created from a single definition.
The caller must hold the GIL.
- Return 0 on success or -1 on failure.
+ Return ``-1`` with an exception set on error, ``0`` on success.
.. versionadded:: 3.3
.. c:function:: int PyState_RemoveModule(PyModuleDef *def)
Removes the module object created from *def* from the interpreter state.
- Return 0 on success or -1 on failure.
+ Return ``-1`` with an exception set on error, ``0`` on success.
The caller must hold the GIL.
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
index 13d3c5af956905..ad8b5935258fa7 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -51,8 +51,8 @@ Number Protocol
Return a reasonable approximation for the mathematical value of *o1* divided by
*o2*, or ``NULL`` on failure. The return value is "approximate" because binary
- floating point numbers are approximate; it is not possible to represent all real
- numbers in base two. This function can return a floating point value when
+ floating-point numbers are approximate; it is not possible to represent all real
+ numbers in base two. This function can return a floating-point value when
passed two integers. This is the equivalent of the Python expression ``o1 / o2``.
@@ -177,8 +177,8 @@ Number Protocol
Return a reasonable approximation for the mathematical value of *o1* divided by
*o2*, or ``NULL`` on failure. The return value is "approximate" because binary
- floating point numbers are approximate; it is not possible to represent all real
- numbers in base two. This function can return a floating point value when
+ floating-point numbers are approximate; it is not possible to represent all real
+ numbers in base two. This function can return a floating-point value when
passed two integers. The operation is done *in-place* when *o1* supports it.
This is the equivalent of the Python statement ``o1 /= o2``.
diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst
index 9e880c6b7f25ad..819929a0e60ca7 100644
--- a/Doc/c-api/slice.rst
+++ b/Doc/c-api/slice.rst
@@ -23,7 +23,9 @@ Slice Objects
Return a new slice object with the given values. The *start*, *stop*, and
*step* parameters are used as the values of the slice object attributes of
the same names. Any of the values may be ``NULL``, in which case the
- ``None`` will be used for the corresponding attribute. Return ``NULL`` if
+ ``None`` will be used for the corresponding attribute.
+
+ Return ``NULL`` with an exception set if
the new object could not be allocated.
@@ -52,7 +54,7 @@ Slice Objects
of bounds indices are clipped in a manner consistent with the handling of
normal slices.
- Returns ``0`` on success and ``-1`` on error with exception set.
+ Return ``0`` on success and ``-1`` on error with an exception set.
.. note::
This function is considered not safe for resizable sequences.
@@ -95,7 +97,7 @@ Slice Objects
``PY_SSIZE_T_MIN`` to ``PY_SSIZE_T_MIN``, and silently boost the step
values less than ``-PY_SSIZE_T_MAX`` to ``-PY_SSIZE_T_MAX``.
- Return ``-1`` on error, ``0`` on success.
+ Return ``-1`` with an exception set on error, ``0`` on success.
.. versionadded:: 3.6.1
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index f6d865f2f52219..90896572046993 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -1584,7 +1584,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
weak references to the type object itself.
It is an error to set both the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit and
- :c:member:`~PyTypeObject.tp_weaklist`.
+ :c:member:`~PyTypeObject.tp_weaklistoffset`.
**Inheritance:**
@@ -1596,7 +1596,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
**Default:**
If the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit is set in the
- :c:member:`~PyTypeObject.tp_dict` field, then
+ :c:member:`~PyTypeObject.tp_flags` field, then
:c:member:`~PyTypeObject.tp_weaklistoffset` will be set to a negative value,
to indicate that it is unsafe to use this field.
diff --git a/Doc/conf.py b/Doc/conf.py
index e292bdd5003b97..75c65fa2dfc4f5 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -6,9 +6,11 @@
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
+import importlib
import os
import sys
import time
+
sys.path.append(os.path.abspath('tools/extensions'))
sys.path.append(os.path.abspath('includes'))
@@ -18,11 +20,10 @@
# ---------------------
extensions = [
- 'asdl_highlight',
+ 'audit_events',
'c_annotations',
- 'escape4chm',
'glossary_search',
- 'peg_highlight',
+ 'lexers',
'pyspecific',
'sphinx.ext.coverage',
'sphinx.ext.doctest',
@@ -31,7 +32,7 @@
# Skip if downstream redistributors haven't installed it
try:
- import sphinxext.opengraph
+ import sphinxext.opengraph # noqa: F401
except ImportError:
pass
else:
@@ -58,8 +59,8 @@
# We look for the Include/patchlevel.h file in the current Python source tree
# and replace the values accordingly.
-import patchlevel
-version, release = patchlevel.get_version_info()
+# See Doc/tools/extensions/patchlevel.py
+version, release = importlib.import_module('patchlevel').get_version_info()
rst_epilog = f"""
.. |python_version_literal| replace:: ``Python {version}``
@@ -75,7 +76,7 @@
highlight_language = 'python3'
# Minimum version of sphinx required
-needs_sphinx = '4.2'
+needs_sphinx = '6.2.1'
# Create table of contents entries for domain objects (e.g. functions, classes,
# attributes, etc.). Default is True.
@@ -256,6 +257,9 @@
('c:data', 'PyExc_UnicodeWarning'),
('c:data', 'PyExc_UserWarning'),
('c:data', 'PyExc_Warning'),
+ # Undocumented public C macros
+ ('c:macro', 'Py_BUILD_ASSERT'),
+ ('c:macro', 'Py_BUILD_ASSERT_EXPR'),
# 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.
@@ -280,7 +284,8 @@
# Disable Docutils smartquotes for several translations
smartquotes_excludes = {
- 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], 'builders': ['man', 'text'],
+ 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'],
+ 'builders': ['man', 'text'],
}
# Avoid a warning with Sphinx >= 4.0
@@ -301,11 +306,13 @@
'collapsiblesidebar': True,
'issues_url': '/bugs.html',
'license_url': '/license.html',
- 'root_include_title': False # We use the version switcher instead.
+ 'root_include_title': False, # We use the version switcher instead.
}
if os.getenv("READTHEDOCS"):
- html_theme_options["hosted_on"] = 'Read the Docs'
+ html_theme_options["hosted_on"] = (
+ 'Read the Docs'
+ )
# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207
# https://github.com/python/cpython/issues/91207
@@ -319,15 +326,21 @@
# 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")
+is_deployment_preview = os.getenv("READTHEDOCS_VERSION_TYPE") == "external"
+repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL", "")
+repository_url = repository_url.removesuffix(".git")
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")
+ "is_deployment_preview": is_deployment_preview,
+ "repository_url": repository_url or None,
+ "pr_id": os.getenv("READTHEDOCS_VERSION"),
+ "enable_analytics": os.getenv("PYTHON_DOCS_ENABLE_ANALYTICS"),
}
# This 'Last updated on:' timestamp is inserted at the bottom of every page.
-html_last_updated_fmt = time.strftime('%b %d, %Y (%H:%M UTC)', time.gmtime())
+html_time = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
+html_last_updated_fmt = time.strftime(
+ '%b %d, %Y (%H:%M UTC)', time.gmtime(html_time)
+)
# Path to find HTML templates.
templates_path = ['tools/templates']
@@ -387,30 +400,70 @@
# (source start file, target name, title, author, document class [howto/manual]).
_stdauthor = 'Guido van Rossum and the Python development team'
latex_documents = [
- ('c-api/index', 'c-api.tex',
- 'The Python/C API', _stdauthor, 'manual'),
- ('extending/index', 'extending.tex',
- 'Extending and Embedding Python', _stdauthor, 'manual'),
- ('installing/index', 'installing.tex',
- 'Installing Python Modules', _stdauthor, 'manual'),
- ('library/index', 'library.tex',
- 'The Python Library Reference', _stdauthor, 'manual'),
- ('reference/index', 'reference.tex',
- 'The Python Language Reference', _stdauthor, 'manual'),
- ('tutorial/index', 'tutorial.tex',
- 'Python Tutorial', _stdauthor, 'manual'),
- ('using/index', 'using.tex',
- 'Python Setup and Usage', _stdauthor, 'manual'),
- ('faq/index', 'faq.tex',
- 'Python Frequently Asked Questions', _stdauthor, 'manual'),
- ('whatsnew/' + version, 'whatsnew.tex',
- 'What\'s New in Python', 'A. M. Kuchling', 'howto'),
+ ('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'),
+ (
+ 'extending/index',
+ 'extending.tex',
+ 'Extending and Embedding Python',
+ _stdauthor,
+ 'manual',
+ ),
+ (
+ 'installing/index',
+ 'installing.tex',
+ 'Installing Python Modules',
+ _stdauthor,
+ 'manual',
+ ),
+ (
+ 'library/index',
+ 'library.tex',
+ 'The Python Library Reference',
+ _stdauthor,
+ 'manual',
+ ),
+ (
+ 'reference/index',
+ 'reference.tex',
+ 'The Python Language Reference',
+ _stdauthor,
+ 'manual',
+ ),
+ (
+ 'tutorial/index',
+ 'tutorial.tex',
+ 'Python Tutorial',
+ _stdauthor,
+ 'manual',
+ ),
+ (
+ 'using/index',
+ 'using.tex',
+ 'Python Setup and Usage',
+ _stdauthor,
+ 'manual',
+ ),
+ (
+ 'faq/index',
+ 'faq.tex',
+ 'Python Frequently Asked Questions',
+ _stdauthor,
+ 'manual',
+ ),
+ (
+ 'whatsnew/' + version,
+ 'whatsnew.tex',
+ 'What\'s New in Python',
+ 'A. M. Kuchling',
+ 'howto',
+ ),
]
# Collect all HOWTOs individually
-latex_documents.extend(('howto/' + fn[:-4], 'howto-' + fn[:-4] + '.tex',
- '', _stdauthor, 'howto')
- for fn in os.listdir('howto')
- if fn.endswith('.rst') and fn != 'index.rst')
+latex_documents.extend(
+ ('howto/' + fn[:-4], 'howto-' + fn[:-4] + '.tex', '', _stdauthor, 'howto')
+ for fn in os.listdir('howto')
+ if fn.endswith('.rst') and fn != 'index.rst'
+)
# Documents to append as an appendix to all manuals.
latex_appendices = ['glossary', 'about', 'license', 'copyright']
@@ -439,8 +492,7 @@
'test($|_)',
]
-coverage_ignore_classes = [
-]
+coverage_ignore_classes = []
# Glob patterns for C source files for C API coverage, relative to this directory.
coverage_c_path = [
@@ -457,7 +509,7 @@
# The coverage checker will ignore all C items whose names match these regexes
# (using re.match) -- the keys must be the same as in coverage_c_regexes.
coverage_ignore_c_items = {
-# 'cfunction': [...]
+ # 'cfunction': [...]
}
@@ -522,14 +574,16 @@
}
extlinks_detect_hardcoded_links = True
-# Options for extensions
-# ----------------------
+# Options for c_annotations
+# -------------------------
# Relative filename of the data files
refcount_file = 'data/refcounts.dat'
stable_abi_file = 'data/stable_abi.dat'
-# sphinxext-opengraph config
+# Options for sphinxext-opengraph
+# -------------------------------
+
ogp_site_url = 'https://docs.python.org/3/'
ogp_site_name = 'Python documentation'
ogp_image = '_static/og-image.png'
diff --git a/Doc/constraints.txt b/Doc/constraints.txt
index 16b735ea07a72a..ab3b39bf380dad 100644
--- a/Doc/constraints.txt
+++ b/Doc/constraints.txt
@@ -9,16 +9,16 @@ babel<3
colorama<0.5
imagesize<1.5
Jinja2<3.2
-packaging<24
-Pygments>=2.16.1,<3
+packaging<25
+Pygments<3
requests<3
snowballstemmer<3
-sphinxcontrib-applehelp<1.0.5
-sphinxcontrib-devhelp<1.0.6
-sphinxcontrib-htmlhelp<2.0.5
+sphinxcontrib-applehelp<2.1
+sphinxcontrib-devhelp<2.1
+sphinxcontrib-htmlhelp<2.2
sphinxcontrib-jsmath<1.1
-sphinxcontrib-qthelp<1.0.7
-sphinxcontrib-serializinghtml<1.1.10
+sphinxcontrib-qthelp<2.1
+sphinxcontrib-serializinghtml<2.1
# Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above)
MarkupSafe<2.2
diff --git a/Doc/contents.rst b/Doc/contents.rst
index 24ceacb0076b5e..b57f4b09a5dcb6 100644
--- a/Doc/contents.rst
+++ b/Doc/contents.rst
@@ -14,6 +14,7 @@
installing/index.rst
howto/index.rst
faq/index.rst
+ deprecations/index.rst
glossary.rst
about.rst
diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index f112d268129fd1..4aa2b35162d807 100644
--- a/Doc/data/stable_abi.dat
+++ b/Doc/data/stable_abi.dat
@@ -1,868 +1,868 @@
role,name,added,ifdef_note,struct_abi_kind
macro,PY_VECTORCALL_ARGUMENTS_OFFSET,3.12,,
-function,PyAIter_Check,3.10,,
-function,PyArg_Parse,3.2,,
-function,PyArg_ParseTuple,3.2,,
-function,PyArg_ParseTupleAndKeywords,3.2,,
-function,PyArg_UnpackTuple,3.2,,
-function,PyArg_VaParse,3.2,,
-function,PyArg_VaParseTupleAndKeywords,3.2,,
-function,PyArg_ValidateKeywordArguments,3.2,,
-var,PyBaseObject_Type,3.2,,
-function,PyBool_FromLong,3.2,,
-var,PyBool_Type,3.2,,
-function,PyBuffer_FillContiguousStrides,3.11,,
-function,PyBuffer_FillInfo,3.11,,
-function,PyBuffer_FromContiguous,3.11,,
-function,PyBuffer_GetPointer,3.11,,
-function,PyBuffer_IsContiguous,3.11,,
-function,PyBuffer_Release,3.11,,
-function,PyBuffer_SizeFromFormat,3.11,,
-function,PyBuffer_ToContiguous,3.11,,
-var,PyByteArrayIter_Type,3.2,,
-function,PyByteArray_AsString,3.2,,
-function,PyByteArray_Concat,3.2,,
-function,PyByteArray_FromObject,3.2,,
-function,PyByteArray_FromStringAndSize,3.2,,
-function,PyByteArray_Resize,3.2,,
-function,PyByteArray_Size,3.2,,
-var,PyByteArray_Type,3.2,,
-var,PyBytesIter_Type,3.2,,
-function,PyBytes_AsString,3.2,,
-function,PyBytes_AsStringAndSize,3.2,,
-function,PyBytes_Concat,3.2,,
-function,PyBytes_ConcatAndDel,3.2,,
-function,PyBytes_DecodeEscape,3.2,,
-function,PyBytes_FromFormat,3.2,,
-function,PyBytes_FromFormatV,3.2,,
-function,PyBytes_FromObject,3.2,,
-function,PyBytes_FromString,3.2,,
-function,PyBytes_FromStringAndSize,3.2,,
-function,PyBytes_Repr,3.2,,
-function,PyBytes_Size,3.2,,
-var,PyBytes_Type,3.2,,
+func,PyAIter_Check,3.10,,
+func,PyArg_Parse,3.2,,
+func,PyArg_ParseTuple,3.2,,
+func,PyArg_ParseTupleAndKeywords,3.2,,
+func,PyArg_UnpackTuple,3.2,,
+func,PyArg_VaParse,3.2,,
+func,PyArg_VaParseTupleAndKeywords,3.2,,
+func,PyArg_ValidateKeywordArguments,3.2,,
+data,PyBaseObject_Type,3.2,,
+func,PyBool_FromLong,3.2,,
+data,PyBool_Type,3.2,,
+func,PyBuffer_FillContiguousStrides,3.11,,
+func,PyBuffer_FillInfo,3.11,,
+func,PyBuffer_FromContiguous,3.11,,
+func,PyBuffer_GetPointer,3.11,,
+func,PyBuffer_IsContiguous,3.11,,
+func,PyBuffer_Release,3.11,,
+func,PyBuffer_SizeFromFormat,3.11,,
+func,PyBuffer_ToContiguous,3.11,,
+data,PyByteArrayIter_Type,3.2,,
+func,PyByteArray_AsString,3.2,,
+func,PyByteArray_Concat,3.2,,
+func,PyByteArray_FromObject,3.2,,
+func,PyByteArray_FromStringAndSize,3.2,,
+func,PyByteArray_Resize,3.2,,
+func,PyByteArray_Size,3.2,,
+data,PyByteArray_Type,3.2,,
+data,PyBytesIter_Type,3.2,,
+func,PyBytes_AsString,3.2,,
+func,PyBytes_AsStringAndSize,3.2,,
+func,PyBytes_Concat,3.2,,
+func,PyBytes_ConcatAndDel,3.2,,
+func,PyBytes_DecodeEscape,3.2,,
+func,PyBytes_FromFormat,3.2,,
+func,PyBytes_FromFormatV,3.2,,
+func,PyBytes_FromObject,3.2,,
+func,PyBytes_FromString,3.2,,
+func,PyBytes_FromStringAndSize,3.2,,
+func,PyBytes_Repr,3.2,,
+func,PyBytes_Size,3.2,,
+data,PyBytes_Type,3.2,,
type,PyCFunction,3.2,,
type,PyCFunctionWithKeywords,3.2,,
-function,PyCFunction_Call,3.2,,
-function,PyCFunction_GetFlags,3.2,,
-function,PyCFunction_GetFunction,3.2,,
-function,PyCFunction_GetSelf,3.2,,
-function,PyCFunction_New,3.4,,
-function,PyCFunction_NewEx,3.2,,
-var,PyCFunction_Type,3.2,,
-function,PyCMethod_New,3.9,,
-function,PyCallIter_New,3.2,,
-var,PyCallIter_Type,3.2,,
-function,PyCallable_Check,3.2,,
+func,PyCFunction_Call,3.2,,
+func,PyCFunction_GetFlags,3.2,,
+func,PyCFunction_GetFunction,3.2,,
+func,PyCFunction_GetSelf,3.2,,
+func,PyCFunction_New,3.4,,
+func,PyCFunction_NewEx,3.2,,
+data,PyCFunction_Type,3.2,,
+func,PyCMethod_New,3.9,,
+func,PyCallIter_New,3.2,,
+data,PyCallIter_Type,3.2,,
+func,PyCallable_Check,3.2,,
type,PyCapsule_Destructor,3.2,,
-function,PyCapsule_GetContext,3.2,,
-function,PyCapsule_GetDestructor,3.2,,
-function,PyCapsule_GetName,3.2,,
-function,PyCapsule_GetPointer,3.2,,
-function,PyCapsule_Import,3.2,,
-function,PyCapsule_IsValid,3.2,,
-function,PyCapsule_New,3.2,,
-function,PyCapsule_SetContext,3.2,,
-function,PyCapsule_SetDestructor,3.2,,
-function,PyCapsule_SetName,3.2,,
-function,PyCapsule_SetPointer,3.2,,
-var,PyCapsule_Type,3.2,,
-var,PyClassMethodDescr_Type,3.2,,
-function,PyCodec_BackslashReplaceErrors,3.2,,
-function,PyCodec_Decode,3.2,,
-function,PyCodec_Decoder,3.2,,
-function,PyCodec_Encode,3.2,,
-function,PyCodec_Encoder,3.2,,
-function,PyCodec_IgnoreErrors,3.2,,
-function,PyCodec_IncrementalDecoder,3.2,,
-function,PyCodec_IncrementalEncoder,3.2,,
-function,PyCodec_KnownEncoding,3.2,,
-function,PyCodec_LookupError,3.2,,
-function,PyCodec_NameReplaceErrors,3.7,,
-function,PyCodec_Register,3.2,,
-function,PyCodec_RegisterError,3.2,,
-function,PyCodec_ReplaceErrors,3.2,,
-function,PyCodec_StreamReader,3.2,,
-function,PyCodec_StreamWriter,3.2,,
-function,PyCodec_StrictErrors,3.2,,
-function,PyCodec_Unregister,3.10,,
-function,PyCodec_XMLCharRefReplaceErrors,3.2,,
-function,PyComplex_FromDoubles,3.2,,
-function,PyComplex_ImagAsDouble,3.2,,
-function,PyComplex_RealAsDouble,3.2,,
-var,PyComplex_Type,3.2,,
-function,PyDescr_NewClassMethod,3.2,,
-function,PyDescr_NewGetSet,3.2,,
-function,PyDescr_NewMember,3.2,,
-function,PyDescr_NewMethod,3.2,,
-var,PyDictItems_Type,3.2,,
-var,PyDictIterItem_Type,3.2,,
-var,PyDictIterKey_Type,3.2,,
-var,PyDictIterValue_Type,3.2,,
-var,PyDictKeys_Type,3.2,,
-function,PyDictProxy_New,3.2,,
-var,PyDictProxy_Type,3.2,,
-var,PyDictRevIterItem_Type,3.8,,
-var,PyDictRevIterKey_Type,3.8,,
-var,PyDictRevIterValue_Type,3.8,,
-var,PyDictValues_Type,3.2,,
-function,PyDict_Clear,3.2,,
-function,PyDict_Contains,3.2,,
-function,PyDict_Copy,3.2,,
-function,PyDict_DelItem,3.2,,
-function,PyDict_DelItemString,3.2,,
-function,PyDict_GetItem,3.2,,
-function,PyDict_GetItemString,3.2,,
-function,PyDict_GetItemWithError,3.2,,
-function,PyDict_Items,3.2,,
-function,PyDict_Keys,3.2,,
-function,PyDict_Merge,3.2,,
-function,PyDict_MergeFromSeq2,3.2,,
-function,PyDict_New,3.2,,
-function,PyDict_Next,3.2,,
-function,PyDict_SetItem,3.2,,
-function,PyDict_SetItemString,3.2,,
-function,PyDict_Size,3.2,,
-var,PyDict_Type,3.2,,
-function,PyDict_Update,3.2,,
-function,PyDict_Values,3.2,,
-var,PyEllipsis_Type,3.2,,
-var,PyEnum_Type,3.2,,
-function,PyErr_BadArgument,3.2,,
-function,PyErr_BadInternalCall,3.2,,
-function,PyErr_CheckSignals,3.2,,
-function,PyErr_Clear,3.2,,
-function,PyErr_Display,3.2,,
-function,PyErr_DisplayException,3.12,,
-function,PyErr_ExceptionMatches,3.2,,
-function,PyErr_Fetch,3.2,,
-function,PyErr_Format,3.2,,
-function,PyErr_FormatV,3.5,,
-function,PyErr_GetExcInfo,3.7,,
-function,PyErr_GetHandledException,3.11,,
-function,PyErr_GetRaisedException,3.12,,
-function,PyErr_GivenExceptionMatches,3.2,,
-function,PyErr_NewException,3.2,,
-function,PyErr_NewExceptionWithDoc,3.2,,
-function,PyErr_NoMemory,3.2,,
-function,PyErr_NormalizeException,3.2,,
-function,PyErr_Occurred,3.2,,
-function,PyErr_Print,3.2,,
-function,PyErr_PrintEx,3.2,,
-function,PyErr_ProgramText,3.2,,
-function,PyErr_ResourceWarning,3.6,,
-function,PyErr_Restore,3.2,,
-function,PyErr_SetExcFromWindowsErr,3.7,on Windows,
-function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows,
-function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows,
-function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows,
-function,PyErr_SetExcInfo,3.7,,
-function,PyErr_SetFromErrno,3.2,,
-function,PyErr_SetFromErrnoWithFilename,3.2,,
-function,PyErr_SetFromErrnoWithFilenameObject,3.2,,
-function,PyErr_SetFromErrnoWithFilenameObjects,3.7,,
-function,PyErr_SetFromWindowsErr,3.7,on Windows,
-function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows,
-function,PyErr_SetHandledException,3.11,,
-function,PyErr_SetImportError,3.7,,
-function,PyErr_SetImportErrorSubclass,3.6,,
-function,PyErr_SetInterrupt,3.2,,
-function,PyErr_SetInterruptEx,3.10,,
-function,PyErr_SetNone,3.2,,
-function,PyErr_SetObject,3.2,,
-function,PyErr_SetRaisedException,3.12,,
-function,PyErr_SetString,3.2,,
-function,PyErr_SyntaxLocation,3.2,,
-function,PyErr_SyntaxLocationEx,3.7,,
-function,PyErr_WarnEx,3.2,,
-function,PyErr_WarnExplicit,3.2,,
-function,PyErr_WarnFormat,3.2,,
-function,PyErr_WriteUnraisable,3.2,,
-function,PyEval_AcquireLock,3.2,,
-function,PyEval_AcquireThread,3.2,,
-function,PyEval_CallFunction,3.2,,
-function,PyEval_CallMethod,3.2,,
-function,PyEval_CallObjectWithKeywords,3.2,,
-function,PyEval_EvalCode,3.2,,
-function,PyEval_EvalCodeEx,3.2,,
-function,PyEval_EvalFrame,3.2,,
-function,PyEval_EvalFrameEx,3.2,,
-function,PyEval_GetBuiltins,3.2,,
-function,PyEval_GetFrame,3.2,,
-function,PyEval_GetFuncDesc,3.2,,
-function,PyEval_GetFuncName,3.2,,
-function,PyEval_GetGlobals,3.2,,
-function,PyEval_GetLocals,3.2,,
-function,PyEval_InitThreads,3.2,,
-function,PyEval_ReleaseLock,3.2,,
-function,PyEval_ReleaseThread,3.2,,
-function,PyEval_RestoreThread,3.2,,
-function,PyEval_SaveThread,3.2,,
-function,PyEval_ThreadsInitialized,3.2,,
-var,PyExc_ArithmeticError,3.2,,
-var,PyExc_AssertionError,3.2,,
-var,PyExc_AttributeError,3.2,,
-var,PyExc_BaseException,3.2,,
-var,PyExc_BaseExceptionGroup,3.11,,
-var,PyExc_BlockingIOError,3.7,,
-var,PyExc_BrokenPipeError,3.7,,
-var,PyExc_BufferError,3.2,,
-var,PyExc_BytesWarning,3.2,,
-var,PyExc_ChildProcessError,3.7,,
-var,PyExc_ConnectionAbortedError,3.7,,
-var,PyExc_ConnectionError,3.7,,
-var,PyExc_ConnectionRefusedError,3.7,,
-var,PyExc_ConnectionResetError,3.7,,
-var,PyExc_DeprecationWarning,3.2,,
-var,PyExc_EOFError,3.2,,
-var,PyExc_EncodingWarning,3.10,,
-var,PyExc_EnvironmentError,3.2,,
-var,PyExc_Exception,3.2,,
-var,PyExc_FileExistsError,3.7,,
-var,PyExc_FileNotFoundError,3.7,,
-var,PyExc_FloatingPointError,3.2,,
-var,PyExc_FutureWarning,3.2,,
-var,PyExc_GeneratorExit,3.2,,
-var,PyExc_IOError,3.2,,
-var,PyExc_ImportError,3.2,,
-var,PyExc_ImportWarning,3.2,,
-var,PyExc_IndentationError,3.2,,
-var,PyExc_IndexError,3.2,,
-var,PyExc_InterruptedError,3.7,,
-var,PyExc_IsADirectoryError,3.7,,
-var,PyExc_KeyError,3.2,,
-var,PyExc_KeyboardInterrupt,3.2,,
-var,PyExc_LookupError,3.2,,
-var,PyExc_MemoryError,3.2,,
-var,PyExc_ModuleNotFoundError,3.6,,
-var,PyExc_NameError,3.2,,
-var,PyExc_NotADirectoryError,3.7,,
-var,PyExc_NotImplementedError,3.2,,
-var,PyExc_OSError,3.2,,
-var,PyExc_OverflowError,3.2,,
-var,PyExc_PendingDeprecationWarning,3.2,,
-var,PyExc_PermissionError,3.7,,
-var,PyExc_ProcessLookupError,3.7,,
-var,PyExc_RecursionError,3.7,,
-var,PyExc_ReferenceError,3.2,,
-var,PyExc_ResourceWarning,3.7,,
-var,PyExc_RuntimeError,3.2,,
-var,PyExc_RuntimeWarning,3.2,,
-var,PyExc_StopAsyncIteration,3.7,,
-var,PyExc_StopIteration,3.2,,
-var,PyExc_SyntaxError,3.2,,
-var,PyExc_SyntaxWarning,3.2,,
-var,PyExc_SystemError,3.2,,
-var,PyExc_SystemExit,3.2,,
-var,PyExc_TabError,3.2,,
-var,PyExc_TimeoutError,3.7,,
-var,PyExc_TypeError,3.2,,
-var,PyExc_UnboundLocalError,3.2,,
-var,PyExc_UnicodeDecodeError,3.2,,
-var,PyExc_UnicodeEncodeError,3.2,,
-var,PyExc_UnicodeError,3.2,,
-var,PyExc_UnicodeTranslateError,3.2,,
-var,PyExc_UnicodeWarning,3.2,,
-var,PyExc_UserWarning,3.2,,
-var,PyExc_ValueError,3.2,,
-var,PyExc_Warning,3.2,,
-var,PyExc_WindowsError,3.7,on Windows,
-var,PyExc_ZeroDivisionError,3.2,,
-function,PyExceptionClass_Name,3.8,,
-function,PyException_GetArgs,3.12,,
-function,PyException_GetCause,3.2,,
-function,PyException_GetContext,3.2,,
-function,PyException_GetTraceback,3.2,,
-function,PyException_SetArgs,3.12,,
-function,PyException_SetCause,3.2,,
-function,PyException_SetContext,3.2,,
-function,PyException_SetTraceback,3.2,,
-function,PyFile_FromFd,3.2,,
-function,PyFile_GetLine,3.2,,
-function,PyFile_WriteObject,3.2,,
-function,PyFile_WriteString,3.2,,
-var,PyFilter_Type,3.2,,
-function,PyFloat_AsDouble,3.2,,
-function,PyFloat_FromDouble,3.2,,
-function,PyFloat_FromString,3.2,,
-function,PyFloat_GetInfo,3.2,,
-function,PyFloat_GetMax,3.2,,
-function,PyFloat_GetMin,3.2,,
-var,PyFloat_Type,3.2,,
+func,PyCapsule_GetContext,3.2,,
+func,PyCapsule_GetDestructor,3.2,,
+func,PyCapsule_GetName,3.2,,
+func,PyCapsule_GetPointer,3.2,,
+func,PyCapsule_Import,3.2,,
+func,PyCapsule_IsValid,3.2,,
+func,PyCapsule_New,3.2,,
+func,PyCapsule_SetContext,3.2,,
+func,PyCapsule_SetDestructor,3.2,,
+func,PyCapsule_SetName,3.2,,
+func,PyCapsule_SetPointer,3.2,,
+data,PyCapsule_Type,3.2,,
+data,PyClassMethodDescr_Type,3.2,,
+func,PyCodec_BackslashReplaceErrors,3.2,,
+func,PyCodec_Decode,3.2,,
+func,PyCodec_Decoder,3.2,,
+func,PyCodec_Encode,3.2,,
+func,PyCodec_Encoder,3.2,,
+func,PyCodec_IgnoreErrors,3.2,,
+func,PyCodec_IncrementalDecoder,3.2,,
+func,PyCodec_IncrementalEncoder,3.2,,
+func,PyCodec_KnownEncoding,3.2,,
+func,PyCodec_LookupError,3.2,,
+func,PyCodec_NameReplaceErrors,3.7,,
+func,PyCodec_Register,3.2,,
+func,PyCodec_RegisterError,3.2,,
+func,PyCodec_ReplaceErrors,3.2,,
+func,PyCodec_StreamReader,3.2,,
+func,PyCodec_StreamWriter,3.2,,
+func,PyCodec_StrictErrors,3.2,,
+func,PyCodec_Unregister,3.10,,
+func,PyCodec_XMLCharRefReplaceErrors,3.2,,
+func,PyComplex_FromDoubles,3.2,,
+func,PyComplex_ImagAsDouble,3.2,,
+func,PyComplex_RealAsDouble,3.2,,
+data,PyComplex_Type,3.2,,
+func,PyDescr_NewClassMethod,3.2,,
+func,PyDescr_NewGetSet,3.2,,
+func,PyDescr_NewMember,3.2,,
+func,PyDescr_NewMethod,3.2,,
+data,PyDictItems_Type,3.2,,
+data,PyDictIterItem_Type,3.2,,
+data,PyDictIterKey_Type,3.2,,
+data,PyDictIterValue_Type,3.2,,
+data,PyDictKeys_Type,3.2,,
+func,PyDictProxy_New,3.2,,
+data,PyDictProxy_Type,3.2,,
+data,PyDictRevIterItem_Type,3.8,,
+data,PyDictRevIterKey_Type,3.8,,
+data,PyDictRevIterValue_Type,3.8,,
+data,PyDictValues_Type,3.2,,
+func,PyDict_Clear,3.2,,
+func,PyDict_Contains,3.2,,
+func,PyDict_Copy,3.2,,
+func,PyDict_DelItem,3.2,,
+func,PyDict_DelItemString,3.2,,
+func,PyDict_GetItem,3.2,,
+func,PyDict_GetItemString,3.2,,
+func,PyDict_GetItemWithError,3.2,,
+func,PyDict_Items,3.2,,
+func,PyDict_Keys,3.2,,
+func,PyDict_Merge,3.2,,
+func,PyDict_MergeFromSeq2,3.2,,
+func,PyDict_New,3.2,,
+func,PyDict_Next,3.2,,
+func,PyDict_SetItem,3.2,,
+func,PyDict_SetItemString,3.2,,
+func,PyDict_Size,3.2,,
+data,PyDict_Type,3.2,,
+func,PyDict_Update,3.2,,
+func,PyDict_Values,3.2,,
+data,PyEllipsis_Type,3.2,,
+data,PyEnum_Type,3.2,,
+func,PyErr_BadArgument,3.2,,
+func,PyErr_BadInternalCall,3.2,,
+func,PyErr_CheckSignals,3.2,,
+func,PyErr_Clear,3.2,,
+func,PyErr_Display,3.2,,
+func,PyErr_DisplayException,3.12,,
+func,PyErr_ExceptionMatches,3.2,,
+func,PyErr_Fetch,3.2,,
+func,PyErr_Format,3.2,,
+func,PyErr_FormatV,3.5,,
+func,PyErr_GetExcInfo,3.7,,
+func,PyErr_GetHandledException,3.11,,
+func,PyErr_GetRaisedException,3.12,,
+func,PyErr_GivenExceptionMatches,3.2,,
+func,PyErr_NewException,3.2,,
+func,PyErr_NewExceptionWithDoc,3.2,,
+func,PyErr_NoMemory,3.2,,
+func,PyErr_NormalizeException,3.2,,
+func,PyErr_Occurred,3.2,,
+func,PyErr_Print,3.2,,
+func,PyErr_PrintEx,3.2,,
+func,PyErr_ProgramText,3.2,,
+func,PyErr_ResourceWarning,3.6,,
+func,PyErr_Restore,3.2,,
+func,PyErr_SetExcFromWindowsErr,3.7,on Windows,
+func,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows,
+func,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows,
+func,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows,
+func,PyErr_SetExcInfo,3.7,,
+func,PyErr_SetFromErrno,3.2,,
+func,PyErr_SetFromErrnoWithFilename,3.2,,
+func,PyErr_SetFromErrnoWithFilenameObject,3.2,,
+func,PyErr_SetFromErrnoWithFilenameObjects,3.7,,
+func,PyErr_SetFromWindowsErr,3.7,on Windows,
+func,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows,
+func,PyErr_SetHandledException,3.11,,
+func,PyErr_SetImportError,3.7,,
+func,PyErr_SetImportErrorSubclass,3.6,,
+func,PyErr_SetInterrupt,3.2,,
+func,PyErr_SetInterruptEx,3.10,,
+func,PyErr_SetNone,3.2,,
+func,PyErr_SetObject,3.2,,
+func,PyErr_SetRaisedException,3.12,,
+func,PyErr_SetString,3.2,,
+func,PyErr_SyntaxLocation,3.2,,
+func,PyErr_SyntaxLocationEx,3.7,,
+func,PyErr_WarnEx,3.2,,
+func,PyErr_WarnExplicit,3.2,,
+func,PyErr_WarnFormat,3.2,,
+func,PyErr_WriteUnraisable,3.2,,
+func,PyEval_AcquireLock,3.2,,
+func,PyEval_AcquireThread,3.2,,
+func,PyEval_CallFunction,3.2,,
+func,PyEval_CallMethod,3.2,,
+func,PyEval_CallObjectWithKeywords,3.2,,
+func,PyEval_EvalCode,3.2,,
+func,PyEval_EvalCodeEx,3.2,,
+func,PyEval_EvalFrame,3.2,,
+func,PyEval_EvalFrameEx,3.2,,
+func,PyEval_GetBuiltins,3.2,,
+func,PyEval_GetFrame,3.2,,
+func,PyEval_GetFuncDesc,3.2,,
+func,PyEval_GetFuncName,3.2,,
+func,PyEval_GetGlobals,3.2,,
+func,PyEval_GetLocals,3.2,,
+func,PyEval_InitThreads,3.2,,
+func,PyEval_ReleaseLock,3.2,,
+func,PyEval_ReleaseThread,3.2,,
+func,PyEval_RestoreThread,3.2,,
+func,PyEval_SaveThread,3.2,,
+func,PyEval_ThreadsInitialized,3.2,,
+data,PyExc_ArithmeticError,3.2,,
+data,PyExc_AssertionError,3.2,,
+data,PyExc_AttributeError,3.2,,
+data,PyExc_BaseException,3.2,,
+data,PyExc_BaseExceptionGroup,3.11,,
+data,PyExc_BlockingIOError,3.7,,
+data,PyExc_BrokenPipeError,3.7,,
+data,PyExc_BufferError,3.2,,
+data,PyExc_BytesWarning,3.2,,
+data,PyExc_ChildProcessError,3.7,,
+data,PyExc_ConnectionAbortedError,3.7,,
+data,PyExc_ConnectionError,3.7,,
+data,PyExc_ConnectionRefusedError,3.7,,
+data,PyExc_ConnectionResetError,3.7,,
+data,PyExc_DeprecationWarning,3.2,,
+data,PyExc_EOFError,3.2,,
+data,PyExc_EncodingWarning,3.10,,
+data,PyExc_EnvironmentError,3.2,,
+data,PyExc_Exception,3.2,,
+data,PyExc_FileExistsError,3.7,,
+data,PyExc_FileNotFoundError,3.7,,
+data,PyExc_FloatingPointError,3.2,,
+data,PyExc_FutureWarning,3.2,,
+data,PyExc_GeneratorExit,3.2,,
+data,PyExc_IOError,3.2,,
+data,PyExc_ImportError,3.2,,
+data,PyExc_ImportWarning,3.2,,
+data,PyExc_IndentationError,3.2,,
+data,PyExc_IndexError,3.2,,
+data,PyExc_InterruptedError,3.7,,
+data,PyExc_IsADirectoryError,3.7,,
+data,PyExc_KeyError,3.2,,
+data,PyExc_KeyboardInterrupt,3.2,,
+data,PyExc_LookupError,3.2,,
+data,PyExc_MemoryError,3.2,,
+data,PyExc_ModuleNotFoundError,3.6,,
+data,PyExc_NameError,3.2,,
+data,PyExc_NotADirectoryError,3.7,,
+data,PyExc_NotImplementedError,3.2,,
+data,PyExc_OSError,3.2,,
+data,PyExc_OverflowError,3.2,,
+data,PyExc_PendingDeprecationWarning,3.2,,
+data,PyExc_PermissionError,3.7,,
+data,PyExc_ProcessLookupError,3.7,,
+data,PyExc_RecursionError,3.7,,
+data,PyExc_ReferenceError,3.2,,
+data,PyExc_ResourceWarning,3.7,,
+data,PyExc_RuntimeError,3.2,,
+data,PyExc_RuntimeWarning,3.2,,
+data,PyExc_StopAsyncIteration,3.7,,
+data,PyExc_StopIteration,3.2,,
+data,PyExc_SyntaxError,3.2,,
+data,PyExc_SyntaxWarning,3.2,,
+data,PyExc_SystemError,3.2,,
+data,PyExc_SystemExit,3.2,,
+data,PyExc_TabError,3.2,,
+data,PyExc_TimeoutError,3.7,,
+data,PyExc_TypeError,3.2,,
+data,PyExc_UnboundLocalError,3.2,,
+data,PyExc_UnicodeDecodeError,3.2,,
+data,PyExc_UnicodeEncodeError,3.2,,
+data,PyExc_UnicodeError,3.2,,
+data,PyExc_UnicodeTranslateError,3.2,,
+data,PyExc_UnicodeWarning,3.2,,
+data,PyExc_UserWarning,3.2,,
+data,PyExc_ValueError,3.2,,
+data,PyExc_Warning,3.2,,
+data,PyExc_WindowsError,3.7,on Windows,
+data,PyExc_ZeroDivisionError,3.2,,
+func,PyExceptionClass_Name,3.8,,
+func,PyException_GetArgs,3.12,,
+func,PyException_GetCause,3.2,,
+func,PyException_GetContext,3.2,,
+func,PyException_GetTraceback,3.2,,
+func,PyException_SetArgs,3.12,,
+func,PyException_SetCause,3.2,,
+func,PyException_SetContext,3.2,,
+func,PyException_SetTraceback,3.2,,
+func,PyFile_FromFd,3.2,,
+func,PyFile_GetLine,3.2,,
+func,PyFile_WriteObject,3.2,,
+func,PyFile_WriteString,3.2,,
+data,PyFilter_Type,3.2,,
+func,PyFloat_AsDouble,3.2,,
+func,PyFloat_FromDouble,3.2,,
+func,PyFloat_FromString,3.2,,
+func,PyFloat_GetInfo,3.2,,
+func,PyFloat_GetMax,3.2,,
+func,PyFloat_GetMin,3.2,,
+data,PyFloat_Type,3.2,,
type,PyFrameObject,3.2,,opaque
-function,PyFrame_GetCode,3.10,,
-function,PyFrame_GetLineNumber,3.10,,
-function,PyFrozenSet_New,3.2,,
-var,PyFrozenSet_Type,3.2,,
-function,PyGC_Collect,3.2,,
-function,PyGC_Disable,3.10,,
-function,PyGC_Enable,3.10,,
-function,PyGC_IsEnabled,3.10,,
-function,PyGILState_Ensure,3.2,,
-function,PyGILState_GetThisThreadState,3.2,,
-function,PyGILState_Release,3.2,,
+func,PyFrame_GetCode,3.10,,
+func,PyFrame_GetLineNumber,3.10,,
+func,PyFrozenSet_New,3.2,,
+data,PyFrozenSet_Type,3.2,,
+func,PyGC_Collect,3.2,,
+func,PyGC_Disable,3.10,,
+func,PyGC_Enable,3.10,,
+func,PyGC_IsEnabled,3.10,,
+func,PyGILState_Ensure,3.2,,
+func,PyGILState_GetThisThreadState,3.2,,
+func,PyGILState_Release,3.2,,
type,PyGILState_STATE,3.2,,
type,PyGetSetDef,3.2,,full-abi
-var,PyGetSetDescr_Type,3.2,,
-function,PyImport_AddModule,3.2,,
-function,PyImport_AddModuleObject,3.7,,
-function,PyImport_AppendInittab,3.2,,
-function,PyImport_ExecCodeModule,3.2,,
-function,PyImport_ExecCodeModuleEx,3.2,,
-function,PyImport_ExecCodeModuleObject,3.7,,
-function,PyImport_ExecCodeModuleWithPathnames,3.2,,
-function,PyImport_GetImporter,3.2,,
-function,PyImport_GetMagicNumber,3.2,,
-function,PyImport_GetMagicTag,3.2,,
-function,PyImport_GetModule,3.8,,
-function,PyImport_GetModuleDict,3.2,,
-function,PyImport_Import,3.2,,
-function,PyImport_ImportFrozenModule,3.2,,
-function,PyImport_ImportFrozenModuleObject,3.7,,
-function,PyImport_ImportModule,3.2,,
-function,PyImport_ImportModuleLevel,3.2,,
-function,PyImport_ImportModuleLevelObject,3.7,,
-function,PyImport_ImportModuleNoBlock,3.2,,
-function,PyImport_ReloadModule,3.2,,
-function,PyIndex_Check,3.8,,
+data,PyGetSetDescr_Type,3.2,,
+func,PyImport_AddModule,3.2,,
+func,PyImport_AddModuleObject,3.7,,
+func,PyImport_AppendInittab,3.2,,
+func,PyImport_ExecCodeModule,3.2,,
+func,PyImport_ExecCodeModuleEx,3.2,,
+func,PyImport_ExecCodeModuleObject,3.7,,
+func,PyImport_ExecCodeModuleWithPathnames,3.2,,
+func,PyImport_GetImporter,3.2,,
+func,PyImport_GetMagicNumber,3.2,,
+func,PyImport_GetMagicTag,3.2,,
+func,PyImport_GetModule,3.8,,
+func,PyImport_GetModuleDict,3.2,,
+func,PyImport_Import,3.2,,
+func,PyImport_ImportFrozenModule,3.2,,
+func,PyImport_ImportFrozenModuleObject,3.7,,
+func,PyImport_ImportModule,3.2,,
+func,PyImport_ImportModuleLevel,3.2,,
+func,PyImport_ImportModuleLevelObject,3.7,,
+func,PyImport_ImportModuleNoBlock,3.2,,
+func,PyImport_ReloadModule,3.2,,
+func,PyIndex_Check,3.8,,
type,PyInterpreterState,3.2,,opaque
-function,PyInterpreterState_Clear,3.2,,
-function,PyInterpreterState_Delete,3.2,,
-function,PyInterpreterState_Get,3.9,,
-function,PyInterpreterState_GetDict,3.8,,
-function,PyInterpreterState_GetID,3.7,,
-function,PyInterpreterState_New,3.2,,
-function,PyIter_Check,3.8,,
-function,PyIter_Next,3.2,,
-function,PyIter_Send,3.10,,
-var,PyListIter_Type,3.2,,
-var,PyListRevIter_Type,3.2,,
-function,PyList_Append,3.2,,
-function,PyList_AsTuple,3.2,,
-function,PyList_GetItem,3.2,,
-function,PyList_GetSlice,3.2,,
-function,PyList_Insert,3.2,,
-function,PyList_New,3.2,,
-function,PyList_Reverse,3.2,,
-function,PyList_SetItem,3.2,,
-function,PyList_SetSlice,3.2,,
-function,PyList_Size,3.2,,
-function,PyList_Sort,3.2,,
-var,PyList_Type,3.2,,
+func,PyInterpreterState_Clear,3.2,,
+func,PyInterpreterState_Delete,3.2,,
+func,PyInterpreterState_Get,3.9,,
+func,PyInterpreterState_GetDict,3.8,,
+func,PyInterpreterState_GetID,3.7,,
+func,PyInterpreterState_New,3.2,,
+func,PyIter_Check,3.8,,
+func,PyIter_Next,3.2,,
+func,PyIter_Send,3.10,,
+data,PyListIter_Type,3.2,,
+data,PyListRevIter_Type,3.2,,
+func,PyList_Append,3.2,,
+func,PyList_AsTuple,3.2,,
+func,PyList_GetItem,3.2,,
+func,PyList_GetSlice,3.2,,
+func,PyList_Insert,3.2,,
+func,PyList_New,3.2,,
+func,PyList_Reverse,3.2,,
+func,PyList_SetItem,3.2,,
+func,PyList_SetSlice,3.2,,
+func,PyList_Size,3.2,,
+func,PyList_Sort,3.2,,
+data,PyList_Type,3.2,,
type,PyLongObject,3.2,,opaque
-var,PyLongRangeIter_Type,3.2,,
-function,PyLong_AsDouble,3.2,,
-function,PyLong_AsLong,3.2,,
-function,PyLong_AsLongAndOverflow,3.2,,
-function,PyLong_AsLongLong,3.2,,
-function,PyLong_AsLongLongAndOverflow,3.2,,
-function,PyLong_AsSize_t,3.2,,
-function,PyLong_AsSsize_t,3.2,,
-function,PyLong_AsUnsignedLong,3.2,,
-function,PyLong_AsUnsignedLongLong,3.2,,
-function,PyLong_AsUnsignedLongLongMask,3.2,,
-function,PyLong_AsUnsignedLongMask,3.2,,
-function,PyLong_AsVoidPtr,3.2,,
-function,PyLong_FromDouble,3.2,,
-function,PyLong_FromLong,3.2,,
-function,PyLong_FromLongLong,3.2,,
-function,PyLong_FromSize_t,3.2,,
-function,PyLong_FromSsize_t,3.2,,
-function,PyLong_FromString,3.2,,
-function,PyLong_FromUnsignedLong,3.2,,
-function,PyLong_FromUnsignedLongLong,3.2,,
-function,PyLong_FromVoidPtr,3.2,,
-function,PyLong_GetInfo,3.2,,
-var,PyLong_Type,3.2,,
-var,PyMap_Type,3.2,,
-function,PyMapping_Check,3.2,,
-function,PyMapping_GetItemString,3.2,,
-function,PyMapping_HasKey,3.2,,
-function,PyMapping_HasKeyString,3.2,,
-function,PyMapping_Items,3.2,,
-function,PyMapping_Keys,3.2,,
-function,PyMapping_Length,3.2,,
-function,PyMapping_SetItemString,3.2,,
-function,PyMapping_Size,3.2,,
-function,PyMapping_Values,3.2,,
-function,PyMem_Calloc,3.7,,
-function,PyMem_Free,3.2,,
-function,PyMem_Malloc,3.2,,
-function,PyMem_Realloc,3.2,,
+data,PyLongRangeIter_Type,3.2,,
+func,PyLong_AsDouble,3.2,,
+func,PyLong_AsLong,3.2,,
+func,PyLong_AsLongAndOverflow,3.2,,
+func,PyLong_AsLongLong,3.2,,
+func,PyLong_AsLongLongAndOverflow,3.2,,
+func,PyLong_AsSize_t,3.2,,
+func,PyLong_AsSsize_t,3.2,,
+func,PyLong_AsUnsignedLong,3.2,,
+func,PyLong_AsUnsignedLongLong,3.2,,
+func,PyLong_AsUnsignedLongLongMask,3.2,,
+func,PyLong_AsUnsignedLongMask,3.2,,
+func,PyLong_AsVoidPtr,3.2,,
+func,PyLong_FromDouble,3.2,,
+func,PyLong_FromLong,3.2,,
+func,PyLong_FromLongLong,3.2,,
+func,PyLong_FromSize_t,3.2,,
+func,PyLong_FromSsize_t,3.2,,
+func,PyLong_FromString,3.2,,
+func,PyLong_FromUnsignedLong,3.2,,
+func,PyLong_FromUnsignedLongLong,3.2,,
+func,PyLong_FromVoidPtr,3.2,,
+func,PyLong_GetInfo,3.2,,
+data,PyLong_Type,3.2,,
+data,PyMap_Type,3.2,,
+func,PyMapping_Check,3.2,,
+func,PyMapping_GetItemString,3.2,,
+func,PyMapping_HasKey,3.2,,
+func,PyMapping_HasKeyString,3.2,,
+func,PyMapping_Items,3.2,,
+func,PyMapping_Keys,3.2,,
+func,PyMapping_Length,3.2,,
+func,PyMapping_SetItemString,3.2,,
+func,PyMapping_Size,3.2,,
+func,PyMapping_Values,3.2,,
+func,PyMem_Calloc,3.7,,
+func,PyMem_Free,3.2,,
+func,PyMem_Malloc,3.2,,
+func,PyMem_Realloc,3.2,,
type,PyMemberDef,3.2,,full-abi
-var,PyMemberDescr_Type,3.2,,
-function,PyMember_GetOne,3.2,,
-function,PyMember_SetOne,3.2,,
-function,PyMemoryView_FromBuffer,3.11,,
-function,PyMemoryView_FromMemory,3.7,,
-function,PyMemoryView_FromObject,3.2,,
-function,PyMemoryView_GetContiguous,3.2,,
-var,PyMemoryView_Type,3.2,,
+data,PyMemberDescr_Type,3.2,,
+func,PyMember_GetOne,3.2,,
+func,PyMember_SetOne,3.2,,
+func,PyMemoryView_FromBuffer,3.11,,
+func,PyMemoryView_FromMemory,3.7,,
+func,PyMemoryView_FromObject,3.2,,
+func,PyMemoryView_GetContiguous,3.2,,
+data,PyMemoryView_Type,3.2,,
type,PyMethodDef,3.2,,full-abi
-var,PyMethodDescr_Type,3.2,,
+data,PyMethodDescr_Type,3.2,,
type,PyModuleDef,3.2,,full-abi
type,PyModuleDef_Base,3.2,,full-abi
-function,PyModuleDef_Init,3.5,,
-var,PyModuleDef_Type,3.5,,
-function,PyModule_AddFunctions,3.7,,
-function,PyModule_AddIntConstant,3.2,,
-function,PyModule_AddObject,3.2,,
-function,PyModule_AddObjectRef,3.10,,
-function,PyModule_AddStringConstant,3.2,,
-function,PyModule_AddType,3.10,,
-function,PyModule_Create2,3.2,,
-function,PyModule_ExecDef,3.7,,
-function,PyModule_FromDefAndSpec2,3.7,,
-function,PyModule_GetDef,3.2,,
-function,PyModule_GetDict,3.2,,
-function,PyModule_GetFilename,3.2,,
-function,PyModule_GetFilenameObject,3.2,,
-function,PyModule_GetName,3.2,,
-function,PyModule_GetNameObject,3.7,,
-function,PyModule_GetState,3.2,,
-function,PyModule_New,3.2,,
-function,PyModule_NewObject,3.7,,
-function,PyModule_SetDocString,3.7,,
-var,PyModule_Type,3.2,,
-function,PyNumber_Absolute,3.2,,
-function,PyNumber_Add,3.2,,
-function,PyNumber_And,3.2,,
-function,PyNumber_AsSsize_t,3.2,,
-function,PyNumber_Check,3.2,,
-function,PyNumber_Divmod,3.2,,
-function,PyNumber_Float,3.2,,
-function,PyNumber_FloorDivide,3.2,,
-function,PyNumber_InPlaceAdd,3.2,,
-function,PyNumber_InPlaceAnd,3.2,,
-function,PyNumber_InPlaceFloorDivide,3.2,,
-function,PyNumber_InPlaceLshift,3.2,,
-function,PyNumber_InPlaceMatrixMultiply,3.7,,
-function,PyNumber_InPlaceMultiply,3.2,,
-function,PyNumber_InPlaceOr,3.2,,
-function,PyNumber_InPlacePower,3.2,,
-function,PyNumber_InPlaceRemainder,3.2,,
-function,PyNumber_InPlaceRshift,3.2,,
-function,PyNumber_InPlaceSubtract,3.2,,
-function,PyNumber_InPlaceTrueDivide,3.2,,
-function,PyNumber_InPlaceXor,3.2,,
-function,PyNumber_Index,3.2,,
-function,PyNumber_Invert,3.2,,
-function,PyNumber_Long,3.2,,
-function,PyNumber_Lshift,3.2,,
-function,PyNumber_MatrixMultiply,3.7,,
-function,PyNumber_Multiply,3.2,,
-function,PyNumber_Negative,3.2,,
-function,PyNumber_Or,3.2,,
-function,PyNumber_Positive,3.2,,
-function,PyNumber_Power,3.2,,
-function,PyNumber_Remainder,3.2,,
-function,PyNumber_Rshift,3.2,,
-function,PyNumber_Subtract,3.2,,
-function,PyNumber_ToBase,3.2,,
-function,PyNumber_TrueDivide,3.2,,
-function,PyNumber_Xor,3.2,,
-function,PyOS_AfterFork,3.2,on platforms with fork(),
-function,PyOS_AfterFork_Child,3.7,on platforms with fork(),
-function,PyOS_AfterFork_Parent,3.7,on platforms with fork(),
-function,PyOS_BeforeFork,3.7,on platforms with fork(),
-function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK,
-function,PyOS_FSPath,3.6,,
-var,PyOS_InputHook,3.2,,
-function,PyOS_InterruptOccurred,3.2,,
-function,PyOS_double_to_string,3.2,,
-function,PyOS_getsig,3.2,,
-function,PyOS_mystricmp,3.2,,
-function,PyOS_mystrnicmp,3.2,,
-function,PyOS_setsig,3.2,,
+func,PyModuleDef_Init,3.5,,
+data,PyModuleDef_Type,3.5,,
+func,PyModule_AddFunctions,3.7,,
+func,PyModule_AddIntConstant,3.2,,
+func,PyModule_AddObject,3.2,,
+func,PyModule_AddObjectRef,3.10,,
+func,PyModule_AddStringConstant,3.2,,
+func,PyModule_AddType,3.10,,
+func,PyModule_Create2,3.2,,
+func,PyModule_ExecDef,3.7,,
+func,PyModule_FromDefAndSpec2,3.7,,
+func,PyModule_GetDef,3.2,,
+func,PyModule_GetDict,3.2,,
+func,PyModule_GetFilename,3.2,,
+func,PyModule_GetFilenameObject,3.2,,
+func,PyModule_GetName,3.2,,
+func,PyModule_GetNameObject,3.7,,
+func,PyModule_GetState,3.2,,
+func,PyModule_New,3.2,,
+func,PyModule_NewObject,3.7,,
+func,PyModule_SetDocString,3.7,,
+data,PyModule_Type,3.2,,
+func,PyNumber_Absolute,3.2,,
+func,PyNumber_Add,3.2,,
+func,PyNumber_And,3.2,,
+func,PyNumber_AsSsize_t,3.2,,
+func,PyNumber_Check,3.2,,
+func,PyNumber_Divmod,3.2,,
+func,PyNumber_Float,3.2,,
+func,PyNumber_FloorDivide,3.2,,
+func,PyNumber_InPlaceAdd,3.2,,
+func,PyNumber_InPlaceAnd,3.2,,
+func,PyNumber_InPlaceFloorDivide,3.2,,
+func,PyNumber_InPlaceLshift,3.2,,
+func,PyNumber_InPlaceMatrixMultiply,3.7,,
+func,PyNumber_InPlaceMultiply,3.2,,
+func,PyNumber_InPlaceOr,3.2,,
+func,PyNumber_InPlacePower,3.2,,
+func,PyNumber_InPlaceRemainder,3.2,,
+func,PyNumber_InPlaceRshift,3.2,,
+func,PyNumber_InPlaceSubtract,3.2,,
+func,PyNumber_InPlaceTrueDivide,3.2,,
+func,PyNumber_InPlaceXor,3.2,,
+func,PyNumber_Index,3.2,,
+func,PyNumber_Invert,3.2,,
+func,PyNumber_Long,3.2,,
+func,PyNumber_Lshift,3.2,,
+func,PyNumber_MatrixMultiply,3.7,,
+func,PyNumber_Multiply,3.2,,
+func,PyNumber_Negative,3.2,,
+func,PyNumber_Or,3.2,,
+func,PyNumber_Positive,3.2,,
+func,PyNumber_Power,3.2,,
+func,PyNumber_Remainder,3.2,,
+func,PyNumber_Rshift,3.2,,
+func,PyNumber_Subtract,3.2,,
+func,PyNumber_ToBase,3.2,,
+func,PyNumber_TrueDivide,3.2,,
+func,PyNumber_Xor,3.2,,
+func,PyOS_AfterFork,3.2,on platforms with fork(),
+func,PyOS_AfterFork_Child,3.7,on platforms with fork(),
+func,PyOS_AfterFork_Parent,3.7,on platforms with fork(),
+func,PyOS_BeforeFork,3.7,on platforms with fork(),
+func,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK,
+func,PyOS_FSPath,3.6,,
+data,PyOS_InputHook,3.2,,
+func,PyOS_InterruptOccurred,3.2,,
+func,PyOS_double_to_string,3.2,,
+func,PyOS_getsig,3.2,,
+func,PyOS_mystricmp,3.2,,
+func,PyOS_mystrnicmp,3.2,,
+func,PyOS_setsig,3.2,,
type,PyOS_sighandler_t,3.2,,
-function,PyOS_snprintf,3.2,,
-function,PyOS_string_to_double,3.2,,
-function,PyOS_strtol,3.2,,
-function,PyOS_strtoul,3.2,,
-function,PyOS_vsnprintf,3.2,,
+func,PyOS_snprintf,3.2,,
+func,PyOS_string_to_double,3.2,,
+func,PyOS_strtol,3.2,,
+func,PyOS_strtoul,3.2,,
+func,PyOS_vsnprintf,3.2,,
type,PyObject,3.2,,members
member,PyObject.ob_refcnt,3.2,,
member,PyObject.ob_type,3.2,,
-function,PyObject_ASCII,3.2,,
-function,PyObject_AsCharBuffer,3.2,,
-function,PyObject_AsFileDescriptor,3.2,,
-function,PyObject_AsReadBuffer,3.2,,
-function,PyObject_AsWriteBuffer,3.2,,
-function,PyObject_Bytes,3.2,,
-function,PyObject_Call,3.2,,
-function,PyObject_CallFunction,3.2,,
-function,PyObject_CallFunctionObjArgs,3.2,,
-function,PyObject_CallMethod,3.2,,
-function,PyObject_CallMethodObjArgs,3.2,,
-function,PyObject_CallNoArgs,3.10,,
-function,PyObject_CallObject,3.2,,
-function,PyObject_Calloc,3.7,,
-function,PyObject_CheckBuffer,3.11,,
-function,PyObject_CheckReadBuffer,3.2,,
-function,PyObject_ClearWeakRefs,3.2,,
-function,PyObject_CopyData,3.11,,
-function,PyObject_DelItem,3.2,,
-function,PyObject_DelItemString,3.2,,
-function,PyObject_Dir,3.2,,
-function,PyObject_Format,3.2,,
-function,PyObject_Free,3.2,,
-function,PyObject_GC_Del,3.2,,
-function,PyObject_GC_IsFinalized,3.9,,
-function,PyObject_GC_IsTracked,3.9,,
-function,PyObject_GC_Track,3.2,,
-function,PyObject_GC_UnTrack,3.2,,
-function,PyObject_GenericGetAttr,3.2,,
-function,PyObject_GenericGetDict,3.10,,
-function,PyObject_GenericSetAttr,3.2,,
-function,PyObject_GenericSetDict,3.7,,
-function,PyObject_GetAIter,3.10,,
-function,PyObject_GetAttr,3.2,,
-function,PyObject_GetAttrString,3.2,,
-function,PyObject_GetBuffer,3.11,,
-function,PyObject_GetItem,3.2,,
-function,PyObject_GetIter,3.2,,
-function,PyObject_GetTypeData,3.12,,
-function,PyObject_HasAttr,3.2,,
-function,PyObject_HasAttrString,3.2,,
-function,PyObject_Hash,3.2,,
-function,PyObject_HashNotImplemented,3.2,,
-function,PyObject_Init,3.2,,
-function,PyObject_InitVar,3.2,,
-function,PyObject_IsInstance,3.2,,
-function,PyObject_IsSubclass,3.2,,
-function,PyObject_IsTrue,3.2,,
-function,PyObject_Length,3.2,,
-function,PyObject_Malloc,3.2,,
-function,PyObject_Not,3.2,,
-function,PyObject_Realloc,3.2,,
-function,PyObject_Repr,3.2,,
-function,PyObject_RichCompare,3.2,,
-function,PyObject_RichCompareBool,3.2,,
-function,PyObject_SelfIter,3.2,,
-function,PyObject_SetAttr,3.2,,
-function,PyObject_SetAttrString,3.2,,
-function,PyObject_SetItem,3.2,,
-function,PyObject_Size,3.2,,
-function,PyObject_Str,3.2,,
-function,PyObject_Type,3.2,,
-function,PyObject_Vectorcall,3.12,,
-function,PyObject_VectorcallMethod,3.12,,
-var,PyProperty_Type,3.2,,
-var,PyRangeIter_Type,3.2,,
-var,PyRange_Type,3.2,,
-var,PyReversed_Type,3.2,,
-function,PySeqIter_New,3.2,,
-var,PySeqIter_Type,3.2,,
-function,PySequence_Check,3.2,,
-function,PySequence_Concat,3.2,,
-function,PySequence_Contains,3.2,,
-function,PySequence_Count,3.2,,
-function,PySequence_DelItem,3.2,,
-function,PySequence_DelSlice,3.2,,
-function,PySequence_Fast,3.2,,
-function,PySequence_GetItem,3.2,,
-function,PySequence_GetSlice,3.2,,
-function,PySequence_In,3.2,,
-function,PySequence_InPlaceConcat,3.2,,
-function,PySequence_InPlaceRepeat,3.2,,
-function,PySequence_Index,3.2,,
-function,PySequence_Length,3.2,,
-function,PySequence_List,3.2,,
-function,PySequence_Repeat,3.2,,
-function,PySequence_SetItem,3.2,,
-function,PySequence_SetSlice,3.2,,
-function,PySequence_Size,3.2,,
-function,PySequence_Tuple,3.2,,
-var,PySetIter_Type,3.2,,
-function,PySet_Add,3.2,,
-function,PySet_Clear,3.2,,
-function,PySet_Contains,3.2,,
-function,PySet_Discard,3.2,,
-function,PySet_New,3.2,,
-function,PySet_Pop,3.2,,
-function,PySet_Size,3.2,,
-var,PySet_Type,3.2,,
-function,PySlice_AdjustIndices,3.7,,
-function,PySlice_GetIndices,3.2,,
-function,PySlice_GetIndicesEx,3.2,,
-function,PySlice_New,3.2,,
-var,PySlice_Type,3.2,,
-function,PySlice_Unpack,3.7,,
-function,PyState_AddModule,3.3,,
-function,PyState_FindModule,3.2,,
-function,PyState_RemoveModule,3.3,,
+func,PyObject_ASCII,3.2,,
+func,PyObject_AsCharBuffer,3.2,,
+func,PyObject_AsFileDescriptor,3.2,,
+func,PyObject_AsReadBuffer,3.2,,
+func,PyObject_AsWriteBuffer,3.2,,
+func,PyObject_Bytes,3.2,,
+func,PyObject_Call,3.2,,
+func,PyObject_CallFunction,3.2,,
+func,PyObject_CallFunctionObjArgs,3.2,,
+func,PyObject_CallMethod,3.2,,
+func,PyObject_CallMethodObjArgs,3.2,,
+func,PyObject_CallNoArgs,3.10,,
+func,PyObject_CallObject,3.2,,
+func,PyObject_Calloc,3.7,,
+func,PyObject_CheckBuffer,3.11,,
+func,PyObject_CheckReadBuffer,3.2,,
+func,PyObject_ClearWeakRefs,3.2,,
+func,PyObject_CopyData,3.11,,
+func,PyObject_DelItem,3.2,,
+func,PyObject_DelItemString,3.2,,
+func,PyObject_Dir,3.2,,
+func,PyObject_Format,3.2,,
+func,PyObject_Free,3.2,,
+func,PyObject_GC_Del,3.2,,
+func,PyObject_GC_IsFinalized,3.9,,
+func,PyObject_GC_IsTracked,3.9,,
+func,PyObject_GC_Track,3.2,,
+func,PyObject_GC_UnTrack,3.2,,
+func,PyObject_GenericGetAttr,3.2,,
+func,PyObject_GenericGetDict,3.10,,
+func,PyObject_GenericSetAttr,3.2,,
+func,PyObject_GenericSetDict,3.7,,
+func,PyObject_GetAIter,3.10,,
+func,PyObject_GetAttr,3.2,,
+func,PyObject_GetAttrString,3.2,,
+func,PyObject_GetBuffer,3.11,,
+func,PyObject_GetItem,3.2,,
+func,PyObject_GetIter,3.2,,
+func,PyObject_GetTypeData,3.12,,
+func,PyObject_HasAttr,3.2,,
+func,PyObject_HasAttrString,3.2,,
+func,PyObject_Hash,3.2,,
+func,PyObject_HashNotImplemented,3.2,,
+func,PyObject_Init,3.2,,
+func,PyObject_InitVar,3.2,,
+func,PyObject_IsInstance,3.2,,
+func,PyObject_IsSubclass,3.2,,
+func,PyObject_IsTrue,3.2,,
+func,PyObject_Length,3.2,,
+func,PyObject_Malloc,3.2,,
+func,PyObject_Not,3.2,,
+func,PyObject_Realloc,3.2,,
+func,PyObject_Repr,3.2,,
+func,PyObject_RichCompare,3.2,,
+func,PyObject_RichCompareBool,3.2,,
+func,PyObject_SelfIter,3.2,,
+func,PyObject_SetAttr,3.2,,
+func,PyObject_SetAttrString,3.2,,
+func,PyObject_SetItem,3.2,,
+func,PyObject_Size,3.2,,
+func,PyObject_Str,3.2,,
+func,PyObject_Type,3.2,,
+func,PyObject_Vectorcall,3.12,,
+func,PyObject_VectorcallMethod,3.12,,
+data,PyProperty_Type,3.2,,
+data,PyRangeIter_Type,3.2,,
+data,PyRange_Type,3.2,,
+data,PyReversed_Type,3.2,,
+func,PySeqIter_New,3.2,,
+data,PySeqIter_Type,3.2,,
+func,PySequence_Check,3.2,,
+func,PySequence_Concat,3.2,,
+func,PySequence_Contains,3.2,,
+func,PySequence_Count,3.2,,
+func,PySequence_DelItem,3.2,,
+func,PySequence_DelSlice,3.2,,
+func,PySequence_Fast,3.2,,
+func,PySequence_GetItem,3.2,,
+func,PySequence_GetSlice,3.2,,
+func,PySequence_In,3.2,,
+func,PySequence_InPlaceConcat,3.2,,
+func,PySequence_InPlaceRepeat,3.2,,
+func,PySequence_Index,3.2,,
+func,PySequence_Length,3.2,,
+func,PySequence_List,3.2,,
+func,PySequence_Repeat,3.2,,
+func,PySequence_SetItem,3.2,,
+func,PySequence_SetSlice,3.2,,
+func,PySequence_Size,3.2,,
+func,PySequence_Tuple,3.2,,
+data,PySetIter_Type,3.2,,
+func,PySet_Add,3.2,,
+func,PySet_Clear,3.2,,
+func,PySet_Contains,3.2,,
+func,PySet_Discard,3.2,,
+func,PySet_New,3.2,,
+func,PySet_Pop,3.2,,
+func,PySet_Size,3.2,,
+data,PySet_Type,3.2,,
+func,PySlice_AdjustIndices,3.7,,
+func,PySlice_GetIndices,3.2,,
+func,PySlice_GetIndicesEx,3.2,,
+func,PySlice_New,3.2,,
+data,PySlice_Type,3.2,,
+func,PySlice_Unpack,3.7,,
+func,PyState_AddModule,3.3,,
+func,PyState_FindModule,3.2,,
+func,PyState_RemoveModule,3.3,,
type,PyStructSequence_Desc,3.2,,full-abi
type,PyStructSequence_Field,3.2,,full-abi
-function,PyStructSequence_GetItem,3.2,,
-function,PyStructSequence_New,3.2,,
-function,PyStructSequence_NewType,3.2,,
-function,PyStructSequence_SetItem,3.2,,
-var,PyStructSequence_UnnamedField,3.11,,
-var,PySuper_Type,3.2,,
-function,PySys_AddWarnOption,3.2,,
-function,PySys_AddWarnOptionUnicode,3.2,,
-function,PySys_AddXOption,3.7,,
-function,PySys_FormatStderr,3.2,,
-function,PySys_FormatStdout,3.2,,
-function,PySys_GetObject,3.2,,
-function,PySys_GetXOptions,3.7,,
-function,PySys_HasWarnOptions,3.2,,
-function,PySys_ResetWarnOptions,3.2,,
-function,PySys_SetArgv,3.2,,
-function,PySys_SetArgvEx,3.2,,
-function,PySys_SetObject,3.2,,
-function,PySys_SetPath,3.2,,
-function,PySys_WriteStderr,3.2,,
-function,PySys_WriteStdout,3.2,,
+func,PyStructSequence_GetItem,3.2,,
+func,PyStructSequence_New,3.2,,
+func,PyStructSequence_NewType,3.2,,
+func,PyStructSequence_SetItem,3.2,,
+data,PyStructSequence_UnnamedField,3.11,,
+data,PySuper_Type,3.2,,
+func,PySys_AddWarnOption,3.2,,
+func,PySys_AddWarnOptionUnicode,3.2,,
+func,PySys_AddXOption,3.7,,
+func,PySys_FormatStderr,3.2,,
+func,PySys_FormatStdout,3.2,,
+func,PySys_GetObject,3.2,,
+func,PySys_GetXOptions,3.7,,
+func,PySys_HasWarnOptions,3.2,,
+func,PySys_ResetWarnOptions,3.2,,
+func,PySys_SetArgv,3.2,,
+func,PySys_SetArgvEx,3.2,,
+func,PySys_SetObject,3.2,,
+func,PySys_SetPath,3.2,,
+func,PySys_WriteStderr,3.2,,
+func,PySys_WriteStdout,3.2,,
type,PyThreadState,3.2,,opaque
-function,PyThreadState_Clear,3.2,,
-function,PyThreadState_Delete,3.2,,
-function,PyThreadState_Get,3.2,,
-function,PyThreadState_GetDict,3.2,,
-function,PyThreadState_GetFrame,3.10,,
-function,PyThreadState_GetID,3.10,,
-function,PyThreadState_GetInterpreter,3.10,,
-function,PyThreadState_New,3.2,,
-function,PyThreadState_SetAsyncExc,3.2,,
-function,PyThreadState_Swap,3.2,,
-function,PyThread_GetInfo,3.3,,
-function,PyThread_ReInitTLS,3.2,,
-function,PyThread_acquire_lock,3.2,,
-function,PyThread_acquire_lock_timed,3.2,,
-function,PyThread_allocate_lock,3.2,,
-function,PyThread_create_key,3.2,,
-function,PyThread_delete_key,3.2,,
-function,PyThread_delete_key_value,3.2,,
-function,PyThread_exit_thread,3.2,,
-function,PyThread_free_lock,3.2,,
-function,PyThread_get_key_value,3.2,,
-function,PyThread_get_stacksize,3.2,,
-function,PyThread_get_thread_ident,3.2,,
-function,PyThread_get_thread_native_id,3.2,on platforms with native thread IDs,
-function,PyThread_init_thread,3.2,,
-function,PyThread_release_lock,3.2,,
-function,PyThread_set_key_value,3.2,,
-function,PyThread_set_stacksize,3.2,,
-function,PyThread_start_new_thread,3.2,,
-function,PyThread_tss_alloc,3.7,,
-function,PyThread_tss_create,3.7,,
-function,PyThread_tss_delete,3.7,,
-function,PyThread_tss_free,3.7,,
-function,PyThread_tss_get,3.7,,
-function,PyThread_tss_is_created,3.7,,
-function,PyThread_tss_set,3.7,,
-function,PyTraceBack_Here,3.2,,
-function,PyTraceBack_Print,3.2,,
-var,PyTraceBack_Type,3.2,,
-var,PyTupleIter_Type,3.2,,
-function,PyTuple_GetItem,3.2,,
-function,PyTuple_GetSlice,3.2,,
-function,PyTuple_New,3.2,,
-function,PyTuple_Pack,3.2,,
-function,PyTuple_SetItem,3.2,,
-function,PyTuple_Size,3.2,,
-var,PyTuple_Type,3.2,,
+func,PyThreadState_Clear,3.2,,
+func,PyThreadState_Delete,3.2,,
+func,PyThreadState_Get,3.2,,
+func,PyThreadState_GetDict,3.2,,
+func,PyThreadState_GetFrame,3.10,,
+func,PyThreadState_GetID,3.10,,
+func,PyThreadState_GetInterpreter,3.10,,
+func,PyThreadState_New,3.2,,
+func,PyThreadState_SetAsyncExc,3.2,,
+func,PyThreadState_Swap,3.2,,
+func,PyThread_GetInfo,3.3,,
+func,PyThread_ReInitTLS,3.2,,
+func,PyThread_acquire_lock,3.2,,
+func,PyThread_acquire_lock_timed,3.2,,
+func,PyThread_allocate_lock,3.2,,
+func,PyThread_create_key,3.2,,
+func,PyThread_delete_key,3.2,,
+func,PyThread_delete_key_value,3.2,,
+func,PyThread_exit_thread,3.2,,
+func,PyThread_free_lock,3.2,,
+func,PyThread_get_key_value,3.2,,
+func,PyThread_get_stacksize,3.2,,
+func,PyThread_get_thread_ident,3.2,,
+func,PyThread_get_thread_native_id,3.2,on platforms with native thread IDs,
+func,PyThread_init_thread,3.2,,
+func,PyThread_release_lock,3.2,,
+func,PyThread_set_key_value,3.2,,
+func,PyThread_set_stacksize,3.2,,
+func,PyThread_start_new_thread,3.2,,
+func,PyThread_tss_alloc,3.7,,
+func,PyThread_tss_create,3.7,,
+func,PyThread_tss_delete,3.7,,
+func,PyThread_tss_free,3.7,,
+func,PyThread_tss_get,3.7,,
+func,PyThread_tss_is_created,3.7,,
+func,PyThread_tss_set,3.7,,
+func,PyTraceBack_Here,3.2,,
+func,PyTraceBack_Print,3.2,,
+data,PyTraceBack_Type,3.2,,
+data,PyTupleIter_Type,3.2,,
+func,PyTuple_GetItem,3.2,,
+func,PyTuple_GetSlice,3.2,,
+func,PyTuple_New,3.2,,
+func,PyTuple_Pack,3.2,,
+func,PyTuple_SetItem,3.2,,
+func,PyTuple_Size,3.2,,
+data,PyTuple_Type,3.2,,
type,PyTypeObject,3.2,,opaque
-function,PyType_ClearCache,3.2,,
-function,PyType_FromMetaclass,3.12,,
-function,PyType_FromModuleAndSpec,3.10,,
-function,PyType_FromSpec,3.2,,
-function,PyType_FromSpecWithBases,3.3,,
-function,PyType_GenericAlloc,3.2,,
-function,PyType_GenericNew,3.2,,
-function,PyType_GetFlags,3.2,,
-function,PyType_GetModule,3.10,,
-function,PyType_GetModuleState,3.10,,
-function,PyType_GetName,3.11,,
-function,PyType_GetQualName,3.11,,
-function,PyType_GetSlot,3.4,,
-function,PyType_GetTypeDataSize,3.12,,
-function,PyType_IsSubtype,3.2,,
-function,PyType_Modified,3.2,,
-function,PyType_Ready,3.2,,
+func,PyType_ClearCache,3.2,,
+func,PyType_FromMetaclass,3.12,,
+func,PyType_FromModuleAndSpec,3.10,,
+func,PyType_FromSpec,3.2,,
+func,PyType_FromSpecWithBases,3.3,,
+func,PyType_GenericAlloc,3.2,,
+func,PyType_GenericNew,3.2,,
+func,PyType_GetFlags,3.2,,
+func,PyType_GetModule,3.10,,
+func,PyType_GetModuleState,3.10,,
+func,PyType_GetName,3.11,,
+func,PyType_GetQualName,3.11,,
+func,PyType_GetSlot,3.4,,
+func,PyType_GetTypeDataSize,3.12,,
+func,PyType_IsSubtype,3.2,,
+func,PyType_Modified,3.2,,
+func,PyType_Ready,3.2,,
type,PyType_Slot,3.2,,full-abi
type,PyType_Spec,3.2,,full-abi
-var,PyType_Type,3.2,,
-function,PyUnicodeDecodeError_Create,3.2,,
-function,PyUnicodeDecodeError_GetEncoding,3.2,,
-function,PyUnicodeDecodeError_GetEnd,3.2,,
-function,PyUnicodeDecodeError_GetObject,3.2,,
-function,PyUnicodeDecodeError_GetReason,3.2,,
-function,PyUnicodeDecodeError_GetStart,3.2,,
-function,PyUnicodeDecodeError_SetEnd,3.2,,
-function,PyUnicodeDecodeError_SetReason,3.2,,
-function,PyUnicodeDecodeError_SetStart,3.2,,
-function,PyUnicodeEncodeError_GetEncoding,3.2,,
-function,PyUnicodeEncodeError_GetEnd,3.2,,
-function,PyUnicodeEncodeError_GetObject,3.2,,
-function,PyUnicodeEncodeError_GetReason,3.2,,
-function,PyUnicodeEncodeError_GetStart,3.2,,
-function,PyUnicodeEncodeError_SetEnd,3.2,,
-function,PyUnicodeEncodeError_SetReason,3.2,,
-function,PyUnicodeEncodeError_SetStart,3.2,,
-var,PyUnicodeIter_Type,3.2,,
-function,PyUnicodeTranslateError_GetEnd,3.2,,
-function,PyUnicodeTranslateError_GetObject,3.2,,
-function,PyUnicodeTranslateError_GetReason,3.2,,
-function,PyUnicodeTranslateError_GetStart,3.2,,
-function,PyUnicodeTranslateError_SetEnd,3.2,,
-function,PyUnicodeTranslateError_SetReason,3.2,,
-function,PyUnicodeTranslateError_SetStart,3.2,,
-function,PyUnicode_Append,3.2,,
-function,PyUnicode_AppendAndDel,3.2,,
-function,PyUnicode_AsASCIIString,3.2,,
-function,PyUnicode_AsCharmapString,3.2,,
-function,PyUnicode_AsDecodedObject,3.2,,
-function,PyUnicode_AsDecodedUnicode,3.2,,
-function,PyUnicode_AsEncodedObject,3.2,,
-function,PyUnicode_AsEncodedString,3.2,,
-function,PyUnicode_AsEncodedUnicode,3.2,,
-function,PyUnicode_AsLatin1String,3.2,,
-function,PyUnicode_AsMBCSString,3.7,on Windows,
-function,PyUnicode_AsRawUnicodeEscapeString,3.2,,
-function,PyUnicode_AsUCS4,3.7,,
-function,PyUnicode_AsUCS4Copy,3.7,,
-function,PyUnicode_AsUTF16String,3.2,,
-function,PyUnicode_AsUTF32String,3.2,,
-function,PyUnicode_AsUTF8AndSize,3.10,,
-function,PyUnicode_AsUTF8String,3.2,,
-function,PyUnicode_AsUnicodeEscapeString,3.2,,
-function,PyUnicode_AsWideChar,3.2,,
-function,PyUnicode_AsWideCharString,3.7,,
-function,PyUnicode_BuildEncodingMap,3.2,,
-function,PyUnicode_Compare,3.2,,
-function,PyUnicode_CompareWithASCIIString,3.2,,
-function,PyUnicode_Concat,3.2,,
-function,PyUnicode_Contains,3.2,,
-function,PyUnicode_Count,3.2,,
-function,PyUnicode_Decode,3.2,,
-function,PyUnicode_DecodeASCII,3.2,,
-function,PyUnicode_DecodeCharmap,3.2,,
-function,PyUnicode_DecodeCodePageStateful,3.7,on Windows,
-function,PyUnicode_DecodeFSDefault,3.2,,
-function,PyUnicode_DecodeFSDefaultAndSize,3.2,,
-function,PyUnicode_DecodeLatin1,3.2,,
-function,PyUnicode_DecodeLocale,3.7,,
-function,PyUnicode_DecodeLocaleAndSize,3.7,,
-function,PyUnicode_DecodeMBCS,3.7,on Windows,
-function,PyUnicode_DecodeMBCSStateful,3.7,on Windows,
-function,PyUnicode_DecodeRawUnicodeEscape,3.2,,
-function,PyUnicode_DecodeUTF16,3.2,,
-function,PyUnicode_DecodeUTF16Stateful,3.2,,
-function,PyUnicode_DecodeUTF32,3.2,,
-function,PyUnicode_DecodeUTF32Stateful,3.2,,
-function,PyUnicode_DecodeUTF7,3.2,,
-function,PyUnicode_DecodeUTF7Stateful,3.2,,
-function,PyUnicode_DecodeUTF8,3.2,,
-function,PyUnicode_DecodeUTF8Stateful,3.2,,
-function,PyUnicode_DecodeUnicodeEscape,3.2,,
-function,PyUnicode_EncodeCodePage,3.7,on Windows,
-function,PyUnicode_EncodeFSDefault,3.2,,
-function,PyUnicode_EncodeLocale,3.7,,
-function,PyUnicode_FSConverter,3.2,,
-function,PyUnicode_FSDecoder,3.2,,
-function,PyUnicode_Find,3.2,,
-function,PyUnicode_FindChar,3.7,,
-function,PyUnicode_Format,3.2,,
-function,PyUnicode_FromEncodedObject,3.2,,
-function,PyUnicode_FromFormat,3.2,,
-function,PyUnicode_FromFormatV,3.2,,
-function,PyUnicode_FromObject,3.2,,
-function,PyUnicode_FromOrdinal,3.2,,
-function,PyUnicode_FromString,3.2,,
-function,PyUnicode_FromStringAndSize,3.2,,
-function,PyUnicode_FromWideChar,3.2,,
-function,PyUnicode_GetDefaultEncoding,3.2,,
-function,PyUnicode_GetLength,3.7,,
-function,PyUnicode_InternFromString,3.2,,
-function,PyUnicode_InternInPlace,3.2,,
-function,PyUnicode_IsIdentifier,3.2,,
-function,PyUnicode_Join,3.2,,
-function,PyUnicode_Partition,3.2,,
-function,PyUnicode_RPartition,3.2,,
-function,PyUnicode_RSplit,3.2,,
-function,PyUnicode_ReadChar,3.7,,
-function,PyUnicode_Replace,3.2,,
-function,PyUnicode_Resize,3.2,,
-function,PyUnicode_RichCompare,3.2,,
-function,PyUnicode_Split,3.2,,
-function,PyUnicode_Splitlines,3.2,,
-function,PyUnicode_Substring,3.7,,
-function,PyUnicode_Tailmatch,3.2,,
-function,PyUnicode_Translate,3.2,,
-var,PyUnicode_Type,3.2,,
-function,PyUnicode_WriteChar,3.7,,
+data,PyType_Type,3.2,,
+func,PyUnicodeDecodeError_Create,3.2,,
+func,PyUnicodeDecodeError_GetEncoding,3.2,,
+func,PyUnicodeDecodeError_GetEnd,3.2,,
+func,PyUnicodeDecodeError_GetObject,3.2,,
+func,PyUnicodeDecodeError_GetReason,3.2,,
+func,PyUnicodeDecodeError_GetStart,3.2,,
+func,PyUnicodeDecodeError_SetEnd,3.2,,
+func,PyUnicodeDecodeError_SetReason,3.2,,
+func,PyUnicodeDecodeError_SetStart,3.2,,
+func,PyUnicodeEncodeError_GetEncoding,3.2,,
+func,PyUnicodeEncodeError_GetEnd,3.2,,
+func,PyUnicodeEncodeError_GetObject,3.2,,
+func,PyUnicodeEncodeError_GetReason,3.2,,
+func,PyUnicodeEncodeError_GetStart,3.2,,
+func,PyUnicodeEncodeError_SetEnd,3.2,,
+func,PyUnicodeEncodeError_SetReason,3.2,,
+func,PyUnicodeEncodeError_SetStart,3.2,,
+data,PyUnicodeIter_Type,3.2,,
+func,PyUnicodeTranslateError_GetEnd,3.2,,
+func,PyUnicodeTranslateError_GetObject,3.2,,
+func,PyUnicodeTranslateError_GetReason,3.2,,
+func,PyUnicodeTranslateError_GetStart,3.2,,
+func,PyUnicodeTranslateError_SetEnd,3.2,,
+func,PyUnicodeTranslateError_SetReason,3.2,,
+func,PyUnicodeTranslateError_SetStart,3.2,,
+func,PyUnicode_Append,3.2,,
+func,PyUnicode_AppendAndDel,3.2,,
+func,PyUnicode_AsASCIIString,3.2,,
+func,PyUnicode_AsCharmapString,3.2,,
+func,PyUnicode_AsDecodedObject,3.2,,
+func,PyUnicode_AsDecodedUnicode,3.2,,
+func,PyUnicode_AsEncodedObject,3.2,,
+func,PyUnicode_AsEncodedString,3.2,,
+func,PyUnicode_AsEncodedUnicode,3.2,,
+func,PyUnicode_AsLatin1String,3.2,,
+func,PyUnicode_AsMBCSString,3.7,on Windows,
+func,PyUnicode_AsRawUnicodeEscapeString,3.2,,
+func,PyUnicode_AsUCS4,3.7,,
+func,PyUnicode_AsUCS4Copy,3.7,,
+func,PyUnicode_AsUTF16String,3.2,,
+func,PyUnicode_AsUTF32String,3.2,,
+func,PyUnicode_AsUTF8AndSize,3.10,,
+func,PyUnicode_AsUTF8String,3.2,,
+func,PyUnicode_AsUnicodeEscapeString,3.2,,
+func,PyUnicode_AsWideChar,3.2,,
+func,PyUnicode_AsWideCharString,3.7,,
+func,PyUnicode_BuildEncodingMap,3.2,,
+func,PyUnicode_Compare,3.2,,
+func,PyUnicode_CompareWithASCIIString,3.2,,
+func,PyUnicode_Concat,3.2,,
+func,PyUnicode_Contains,3.2,,
+func,PyUnicode_Count,3.2,,
+func,PyUnicode_Decode,3.2,,
+func,PyUnicode_DecodeASCII,3.2,,
+func,PyUnicode_DecodeCharmap,3.2,,
+func,PyUnicode_DecodeCodePageStateful,3.7,on Windows,
+func,PyUnicode_DecodeFSDefault,3.2,,
+func,PyUnicode_DecodeFSDefaultAndSize,3.2,,
+func,PyUnicode_DecodeLatin1,3.2,,
+func,PyUnicode_DecodeLocale,3.7,,
+func,PyUnicode_DecodeLocaleAndSize,3.7,,
+func,PyUnicode_DecodeMBCS,3.7,on Windows,
+func,PyUnicode_DecodeMBCSStateful,3.7,on Windows,
+func,PyUnicode_DecodeRawUnicodeEscape,3.2,,
+func,PyUnicode_DecodeUTF16,3.2,,
+func,PyUnicode_DecodeUTF16Stateful,3.2,,
+func,PyUnicode_DecodeUTF32,3.2,,
+func,PyUnicode_DecodeUTF32Stateful,3.2,,
+func,PyUnicode_DecodeUTF7,3.2,,
+func,PyUnicode_DecodeUTF7Stateful,3.2,,
+func,PyUnicode_DecodeUTF8,3.2,,
+func,PyUnicode_DecodeUTF8Stateful,3.2,,
+func,PyUnicode_DecodeUnicodeEscape,3.2,,
+func,PyUnicode_EncodeCodePage,3.7,on Windows,
+func,PyUnicode_EncodeFSDefault,3.2,,
+func,PyUnicode_EncodeLocale,3.7,,
+func,PyUnicode_FSConverter,3.2,,
+func,PyUnicode_FSDecoder,3.2,,
+func,PyUnicode_Find,3.2,,
+func,PyUnicode_FindChar,3.7,,
+func,PyUnicode_Format,3.2,,
+func,PyUnicode_FromEncodedObject,3.2,,
+func,PyUnicode_FromFormat,3.2,,
+func,PyUnicode_FromFormatV,3.2,,
+func,PyUnicode_FromObject,3.2,,
+func,PyUnicode_FromOrdinal,3.2,,
+func,PyUnicode_FromString,3.2,,
+func,PyUnicode_FromStringAndSize,3.2,,
+func,PyUnicode_FromWideChar,3.2,,
+func,PyUnicode_GetDefaultEncoding,3.2,,
+func,PyUnicode_GetLength,3.7,,
+func,PyUnicode_InternFromString,3.2,,
+func,PyUnicode_InternInPlace,3.2,,
+func,PyUnicode_IsIdentifier,3.2,,
+func,PyUnicode_Join,3.2,,
+func,PyUnicode_Partition,3.2,,
+func,PyUnicode_RPartition,3.2,,
+func,PyUnicode_RSplit,3.2,,
+func,PyUnicode_ReadChar,3.7,,
+func,PyUnicode_Replace,3.2,,
+func,PyUnicode_Resize,3.2,,
+func,PyUnicode_RichCompare,3.2,,
+func,PyUnicode_Split,3.2,,
+func,PyUnicode_Splitlines,3.2,,
+func,PyUnicode_Substring,3.7,,
+func,PyUnicode_Tailmatch,3.2,,
+func,PyUnicode_Translate,3.2,,
+data,PyUnicode_Type,3.2,,
+func,PyUnicode_WriteChar,3.7,,
type,PyVarObject,3.2,,members
member,PyVarObject.ob_base,3.2,,
member,PyVarObject.ob_size,3.2,,
-function,PyVectorcall_Call,3.12,,
-function,PyVectorcall_NARGS,3.12,,
+func,PyVectorcall_Call,3.12,,
+func,PyVectorcall_NARGS,3.12,,
type,PyWeakReference,3.2,,opaque
-function,PyWeakref_GetObject,3.2,,
-function,PyWeakref_NewProxy,3.2,,
-function,PyWeakref_NewRef,3.2,,
-var,PyWrapperDescr_Type,3.2,,
-function,PyWrapper_New,3.2,,
-var,PyZip_Type,3.2,,
-function,Py_AddPendingCall,3.2,,
-function,Py_AtExit,3.2,,
+func,PyWeakref_GetObject,3.2,,
+func,PyWeakref_NewProxy,3.2,,
+func,PyWeakref_NewRef,3.2,,
+data,PyWrapperDescr_Type,3.2,,
+func,PyWrapper_New,3.2,,
+data,PyZip_Type,3.2,,
+func,Py_AddPendingCall,3.2,,
+func,Py_AtExit,3.2,,
macro,Py_BEGIN_ALLOW_THREADS,3.2,,
macro,Py_BLOCK_THREADS,3.2,,
-function,Py_BuildValue,3.2,,
-function,Py_BytesMain,3.8,,
-function,Py_CompileString,3.2,,
-function,Py_DecRef,3.2,,
-function,Py_DecodeLocale,3.7,,
+func,Py_BuildValue,3.2,,
+func,Py_BytesMain,3.8,,
+func,Py_CompileString,3.2,,
+func,Py_DecRef,3.2,,
+func,Py_DecodeLocale,3.7,,
macro,Py_END_ALLOW_THREADS,3.2,,
-function,Py_EncodeLocale,3.7,,
-function,Py_EndInterpreter,3.2,,
-function,Py_EnterRecursiveCall,3.9,,
-function,Py_Exit,3.2,,
-function,Py_FatalError,3.2,,
-var,Py_FileSystemDefaultEncodeErrors,3.10,,
-var,Py_FileSystemDefaultEncoding,3.2,,
-function,Py_Finalize,3.2,,
-function,Py_FinalizeEx,3.6,,
-function,Py_GenericAlias,3.9,,
-var,Py_GenericAliasType,3.9,,
-function,Py_GetBuildInfo,3.2,,
-function,Py_GetCompiler,3.2,,
-function,Py_GetCopyright,3.2,,
-function,Py_GetExecPrefix,3.2,,
-function,Py_GetPath,3.2,,
-function,Py_GetPlatform,3.2,,
-function,Py_GetPrefix,3.2,,
-function,Py_GetProgramFullPath,3.2,,
-function,Py_GetProgramName,3.2,,
-function,Py_GetPythonHome,3.2,,
-function,Py_GetRecursionLimit,3.2,,
-function,Py_GetVersion,3.2,,
-var,Py_HasFileSystemDefaultEncoding,3.2,,
-function,Py_IncRef,3.2,,
-function,Py_Initialize,3.2,,
-function,Py_InitializeEx,3.2,,
-function,Py_Is,3.10,,
-function,Py_IsFalse,3.10,,
-function,Py_IsInitialized,3.2,,
-function,Py_IsNone,3.10,,
-function,Py_IsTrue,3.10,,
-function,Py_LeaveRecursiveCall,3.9,,
-function,Py_Main,3.2,,
-function,Py_MakePendingCalls,3.2,,
-function,Py_NewInterpreter,3.2,,
-function,Py_NewRef,3.10,,
-function,Py_ReprEnter,3.2,,
-function,Py_ReprLeave,3.2,,
-function,Py_SetPath,3.7,,
-function,Py_SetProgramName,3.2,,
-function,Py_SetPythonHome,3.2,,
-function,Py_SetRecursionLimit,3.2,,
+func,Py_EncodeLocale,3.7,,
+func,Py_EndInterpreter,3.2,,
+func,Py_EnterRecursiveCall,3.9,,
+func,Py_Exit,3.2,,
+func,Py_FatalError,3.2,,
+data,Py_FileSystemDefaultEncodeErrors,3.10,,
+data,Py_FileSystemDefaultEncoding,3.2,,
+func,Py_Finalize,3.2,,
+func,Py_FinalizeEx,3.6,,
+func,Py_GenericAlias,3.9,,
+data,Py_GenericAliasType,3.9,,
+func,Py_GetBuildInfo,3.2,,
+func,Py_GetCompiler,3.2,,
+func,Py_GetCopyright,3.2,,
+func,Py_GetExecPrefix,3.2,,
+func,Py_GetPath,3.2,,
+func,Py_GetPlatform,3.2,,
+func,Py_GetPrefix,3.2,,
+func,Py_GetProgramFullPath,3.2,,
+func,Py_GetProgramName,3.2,,
+func,Py_GetPythonHome,3.2,,
+func,Py_GetRecursionLimit,3.2,,
+func,Py_GetVersion,3.2,,
+data,Py_HasFileSystemDefaultEncoding,3.2,,
+func,Py_IncRef,3.2,,
+func,Py_Initialize,3.2,,
+func,Py_InitializeEx,3.2,,
+func,Py_Is,3.10,,
+func,Py_IsFalse,3.10,,
+func,Py_IsInitialized,3.2,,
+func,Py_IsNone,3.10,,
+func,Py_IsTrue,3.10,,
+func,Py_LeaveRecursiveCall,3.9,,
+func,Py_Main,3.2,,
+func,Py_MakePendingCalls,3.2,,
+func,Py_NewInterpreter,3.2,,
+func,Py_NewRef,3.10,,
+func,Py_ReprEnter,3.2,,
+func,Py_ReprLeave,3.2,,
+func,Py_SetPath,3.7,,
+func,Py_SetProgramName,3.2,,
+func,Py_SetPythonHome,3.2,,
+func,Py_SetRecursionLimit,3.2,,
type,Py_UCS4,3.2,,
macro,Py_UNBLOCK_THREADS,3.2,,
-var,Py_UTF8Mode,3.8,,
-function,Py_VaBuildValue,3.2,,
-var,Py_Version,3.11,,
-function,Py_XNewRef,3.10,,
+data,Py_UTF8Mode,3.8,,
+func,Py_VaBuildValue,3.2,,
+data,Py_Version,3.11,,
+func,Py_XNewRef,3.10,,
type,Py_buffer,3.11,,full-abi
type,Py_intptr_t,3.2,,
type,Py_ssize_t,3.2,,
diff --git a/Doc/deprecations/c-api-pending-removal-in-3.14.rst b/Doc/deprecations/c-api-pending-removal-in-3.14.rst
new file mode 100644
index 00000000000000..369892a75b16eb
--- /dev/null
+++ b/Doc/deprecations/c-api-pending-removal-in-3.14.rst
@@ -0,0 +1,46 @@
+Pending Removal in Python 3.14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The ``ma_version_tag`` field in :c:type:`PyDictObject` for extension modules
+ (:pep:`699`; :gh:`101193`).
+
+* Creating :c:data:`immutable types ` with mutable
+ bases (:gh:`95388`).
+
+* Functions to configure Python's initialization, deprecated in Python 3.11:
+
+ * ``PySys_SetArgvEx()``: set :c:member:`PyConfig.argv` instead.
+ * ``PySys_SetArgv()``: set :c:member:`PyConfig.argv` instead.
+ * ``Py_SetProgramName()``: set :c:member:`PyConfig.program_name` instead.
+ * ``Py_SetPythonHome()``: set :c:member:`PyConfig.home` instead.
+
+ The :c:func:`Py_InitializeFromConfig` API should be used with
+ :c:type:`PyConfig` instead.
+
+* Global configuration variables:
+
+ * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` instead.
+ * :c:var:`Py_VerboseFlag`: use :c:member:`PyConfig.verbose` instead.
+ * :c:var:`Py_QuietFlag`: use :c:member:`PyConfig.quiet` instead.
+ * :c:var:`Py_InteractiveFlag`: use :c:member:`PyConfig.interactive` instead.
+ * :c:var:`Py_InspectFlag`: use :c:member:`PyConfig.inspect` instead.
+ * :c:var:`Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level` instead.
+ * :c:var:`Py_NoSiteFlag`: use :c:member:`PyConfig.site_import` instead.
+ * :c:var:`Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning` instead.
+ * :c:var:`Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings` instead.
+ * :c:var:`Py_IgnoreEnvironmentFlag`: use :c:member:`PyConfig.use_environment` instead.
+ * :c:var:`Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode` instead.
+ * :c:var:`Py_NoUserSiteDirectory`: use :c:member:`PyConfig.user_site_directory` instead.
+ * :c:var:`Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio` instead.
+ * :c:var:`Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed`
+ and :c:member:`PyConfig.hash_seed` instead.
+ * :c:var:`Py_IsolatedFlag`: use :c:member:`PyConfig.isolated` instead.
+ * :c:var:`Py_LegacyWindowsFSEncodingFlag`: use :c:member:`PyPreConfig.legacy_windows_fs_encoding` instead.
+ * :c:var:`Py_LegacyWindowsStdioFlag`: use :c:member:`PyConfig.legacy_windows_stdio` instead.
+ * :c:var:`!Py_FileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` instead.
+ * :c:var:`!Py_HasFileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` instead.
+ * :c:var:`!Py_FileSystemDefaultEncodeErrors`: use :c:member:`PyConfig.filesystem_errors` instead.
+ * :c:var:`!Py_UTF8Mode`: use :c:member:`PyPreConfig.utf8_mode` instead. (see :c:func:`Py_PreInitialize`)
+
+ The :c:func:`Py_InitializeFromConfig` API should be used with
+ :c:type:`PyConfig` instead.
diff --git a/Doc/deprecations/c-api-pending-removal-in-3.15.rst b/Doc/deprecations/c-api-pending-removal-in-3.15.rst
new file mode 100644
index 00000000000000..40d55e712e396c
--- /dev/null
+++ b/Doc/deprecations/c-api-pending-removal-in-3.15.rst
@@ -0,0 +1,20 @@
+Pending Removal in Python 3.15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The bundled copy of ``libmpdecimal``.
+* :c:func:`PyImport_ImportModuleNoBlock`: use :c:func:`PyImport_ImportModule` instead.
+* :c:func:`PyWeakref_GET_OBJECT`: use :c:func:`!PyWeakref_GetRef` instead.
+* :c:func:`PyWeakref_GetObject`: use :c:func:`!PyWeakref_GetRef` instead.
+* :c:type:`!Py_UNICODE_WIDE` type: use :c:type:`wchar_t` instead.
+* :c:type:`Py_UNICODE` type: use :c:type:`wchar_t` instead.
+* Python initialization functions:
+
+ * :c:func:`PySys_ResetWarnOptions`: clear :data:`sys.warnoptions` and
+ :data:`!warnings.filters` instead.
+ * :c:func:`Py_GetExecPrefix`: get :data:`sys.exec_prefix` instead.
+ * :c:func:`Py_GetPath`: get :data:`sys.path` instead.
+ * :c:func:`Py_GetPrefix`: get :data:`sys.prefix` instead.
+ * :c:func:`Py_GetProgramFullPath`: get :data:`sys.executable` instead.
+ * :c:func:`Py_GetProgramName`: get :data:`sys.executable` instead.
+ * :c:func:`Py_GetPythonHome`: get :c:member:`PyConfig.home` or
+ the :envvar:`PYTHONHOME` environment variable instead.
diff --git a/Doc/deprecations/c-api-pending-removal-in-future.rst b/Doc/deprecations/c-api-pending-removal-in-future.rst
new file mode 100644
index 00000000000000..f646be45c8a770
--- /dev/null
+++ b/Doc/deprecations/c-api-pending-removal-in-future.rst
@@ -0,0 +1,31 @@
+Pending Removal in Future Versions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following APIs are deprecated and will be removed,
+although there is currently no date scheduled for their removal.
+
+* :c:macro:`Py_TPFLAGS_HAVE_FINALIZE`: unneeded since Python 3.8.
+* :c:func:`PyErr_Fetch`: use :c:func:`PyErr_GetRaisedException` instead.
+* :c:func:`PyErr_NormalizeException`: use :c:func:`PyErr_GetRaisedException` instead.
+* :c:func:`PyErr_Restore`: use :c:func:`PyErr_SetRaisedException` instead.
+* :c:func:`PyModule_GetFilename`: use :c:func:`PyModule_GetFilenameObject` instead.
+* :c:func:`PyOS_AfterFork`: use :c:func:`PyOS_AfterFork_Child` instead.
+* :c:func:`PySlice_GetIndicesEx`: use :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` instead.
+* :c:func:`!PyUnicode_AsDecodedObject`: use :c:func:`PyCodec_Decode` instead.
+* :c:func:`!PyUnicode_AsDecodedUnicode`: use :c:func:`PyCodec_Decode` instead.
+* :c:func:`!PyUnicode_AsEncodedObject`: use :c:func:`PyCodec_Encode` instead.
+* :c:func:`!PyUnicode_AsEncodedUnicode`: use :c:func:`PyCodec_Encode` instead.
+* :c:func:`PyUnicode_READY`: unneeded since Python 3.12
+* :c:func:`!PyErr_Display`: use :c:func:`PyErr_DisplayException` instead.
+* :c:func:`!_PyErr_ChainExceptions`: use ``_PyErr_ChainExceptions1`` instead.
+* :c:member:`!PyBytesObject.ob_shash` member:
+ call :c:func:`PyObject_Hash` instead.
+* :c:member:`!PyDictObject.ma_version_tag` member.
+* Thread Local Storage (TLS) API:
+
+ * :c:func:`PyThread_create_key`: use :c:func:`PyThread_tss_alloc` instead.
+ * :c:func:`PyThread_delete_key`: use :c:func:`PyThread_tss_free` instead.
+ * :c:func:`PyThread_set_key_value`: use :c:func:`PyThread_tss_set` instead.
+ * :c:func:`PyThread_get_key_value`: use :c:func:`PyThread_tss_get` instead.
+ * :c:func:`PyThread_delete_key_value`: use :c:func:`PyThread_tss_delete` instead.
+ * :c:func:`PyThread_ReInitTLS`: unneeded since Python 3.7.
diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst
new file mode 100644
index 00000000000000..aedea375408c91
--- /dev/null
+++ b/Doc/deprecations/index.rst
@@ -0,0 +1,21 @@
+Deprecations
+============
+
+.. include:: pending-removal-in-3.13.rst
+
+.. include:: pending-removal-in-3.14.rst
+
+.. include:: pending-removal-in-3.15.rst
+
+.. include:: pending-removal-in-3.16.rst
+
+.. include:: pending-removal-in-future.rst
+
+C API Deprecations
+------------------
+
+.. include:: c-api-pending-removal-in-3.14.rst
+
+.. include:: c-api-pending-removal-in-3.15.rst
+
+.. include:: c-api-pending-removal-in-future.rst
diff --git a/Doc/deprecations/pending-removal-in-3.13.rst b/Doc/deprecations/pending-removal-in-3.13.rst
new file mode 100644
index 00000000000000..868f4612014014
--- /dev/null
+++ b/Doc/deprecations/pending-removal-in-3.13.rst
@@ -0,0 +1,52 @@
+Pending Removal in Python 3.13
+------------------------------
+
+Modules (see :pep:`594`):
+
+* :mod:`aifc`
+* :mod:`audioop`
+* :mod:`cgi`
+* :mod:`cgitb`
+* :mod:`chunk`
+* :mod:`crypt`
+* :mod:`imghdr`
+* :mod:`mailcap`
+* :mod:`msilib`
+* :mod:`nis`
+* :mod:`nntplib`
+* :mod:`ossaudiodev`
+* :mod:`pipes`
+* :mod:`sndhdr`
+* :mod:`spwd`
+* :mod:`sunau`
+* :mod:`telnetlib`
+* :mod:`uu`
+* :mod:`xdrlib`
+
+Other modules:
+
+* :mod:`!lib2to3`, and the :program:`2to3` program (:gh:`84540`)
+
+APIs:
+
+* :class:`!configparser.LegacyInterpolation` (:gh:`90765`)
+* ``locale.resetlocale()`` (:gh:`90817`)
+* :meth:`!turtle.RawTurtle.settiltangle` (:gh:`50096`)
+* :func:`!unittest.findTestCases` (:gh:`50096`)
+* :func:`!unittest.getTestCaseNames` (:gh:`50096`)
+* :func:`!unittest.makeSuite` (:gh:`50096`)
+* :meth:`!unittest.TestProgram.usageExit` (:gh:`67048`)
+* :class:`!webbrowser.MacOSX` (:gh:`86421`)
+* :class:`classmethod` descriptor chaining (:gh:`89519`)
+* :mod:`importlib.resources` deprecated methods:
+
+ * ``contents()``
+ * ``is_resource()``
+ * ``open_binary()``
+ * ``open_text()``
+ * ``path()``
+ * ``read_binary()``
+ * ``read_text()``
+
+ Use :func:`importlib.resources.files()` instead. Refer to `importlib-resources: Migrating from Legacy
+ `_ (:gh:`106531`)
diff --git a/Doc/deprecations/pending-removal-in-3.14.rst b/Doc/deprecations/pending-removal-in-3.14.rst
new file mode 100644
index 00000000000000..d1ad3300a9f6d2
--- /dev/null
+++ b/Doc/deprecations/pending-removal-in-3.14.rst
@@ -0,0 +1,118 @@
+Pending Removal in Python 3.14
+------------------------------
+
+* :mod:`argparse`: The *type*, *choices*, and *metavar* parameters
+ of :class:`!argparse.BooleanOptionalAction` are deprecated
+ and will be removed in 3.14.
+ (Contributed by Nikita Sobolev in :gh:`92248`.)
+
+* :mod:`ast`: The following features have been deprecated in documentation
+ since Python 3.8, now cause a :exc:`DeprecationWarning` to be emitted at
+ runtime when they are accessed or used, and will be removed in Python 3.14:
+
+ * :class:`!ast.Num`
+ * :class:`!ast.Str`
+ * :class:`!ast.Bytes`
+ * :class:`!ast.NameConstant`
+ * :class:`!ast.Ellipsis`
+
+ Use :class:`ast.Constant` instead.
+ (Contributed by Serhiy Storchaka in :gh:`90953`.)
+
+* :mod:`asyncio`:
+
+ * The child watcher classes :class:`~asyncio.MultiLoopChildWatcher`,
+ :class:`~asyncio.FastChildWatcher`, :class:`~asyncio.AbstractChildWatcher`
+ and :class:`~asyncio.SafeChildWatcher` are deprecated and
+ will be removed in Python 3.14.
+ (Contributed by Kumar Aditya in :gh:`94597`.)
+
+ * :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`,
+ :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and
+ :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated
+ and will be removed in Python 3.14.
+ (Contributed by Kumar Aditya in :gh:`94597`.)
+
+ * The :meth:`~asyncio.get_event_loop` method of the
+ default event loop policy now emits a :exc:`DeprecationWarning` if there
+ is no current event loop set and it decides to create one.
+ (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.)
+
+* :mod:`collections.abc`: Deprecated :class:`~collections.abc.ByteString`.
+ Prefer :class:`!Sequence` or :class:`~collections.abc.Buffer`.
+ For use in typing, prefer a union, like ``bytes | bytearray``,
+ or :class:`collections.abc.Buffer`.
+ (Contributed by Shantanu Jain in :gh:`91896`.)
+
+* :mod:`email`: Deprecated the *isdst* parameter in :func:`email.utils.localtime`.
+ (Contributed by Alan Williams in :gh:`72346`.)
+
+* :mod:`importlib`: ``__package__`` and ``__cached__`` will cease to be set or
+ taken into consideration by the import system (:gh:`97879`).
+
+* :mod:`importlib.abc` deprecated classes:
+
+ * :class:`!importlib.abc.ResourceReader`
+ * :class:`!importlib.abc.Traversable`
+ * :class:`!importlib.abc.TraversableResources`
+
+ Use :mod:`importlib.resources.abc` classes instead:
+
+ * :class:`importlib.resources.abc.Traversable`
+ * :class:`importlib.resources.abc.TraversableResources`
+
+ (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.)
+
+* :mod:`itertools` had undocumented, inefficient, historically buggy,
+ and inconsistent support for copy, deepcopy, and pickle operations.
+ This will be removed in 3.14 for a significant reduction in code
+ volume and maintenance burden.
+ (Contributed by Raymond Hettinger in :gh:`101588`.)
+
+* :mod:`multiprocessing`: The default start method will change to a safer one on
+ Linux, BSDs, and other non-macOS POSIX platforms where ``'fork'`` is currently
+ the default (:gh:`84559`). Adding a runtime warning about this was deemed too
+ disruptive as the majority of code is not expected to care. Use the
+ :func:`~multiprocessing.get_context` or
+ :func:`~multiprocessing.set_start_method` APIs to explicitly specify when
+ your code *requires* ``'fork'``. See :ref:`multiprocessing-start-methods`.
+
+* :mod:`pathlib`: :meth:`~pathlib.PurePath.is_relative_to` and
+ :meth:`~pathlib.PurePath.relative_to`: passing additional arguments is
+ deprecated.
+
+* :mod:`pkgutil`: :func:`~pkgutil.find_loader` and :func:`~pkgutil.get_loader`
+ now raise :exc:`DeprecationWarning`;
+ use :func:`importlib.util.find_spec` instead.
+ (Contributed by Nikita Sobolev in :gh:`97850`.)
+
+* :mod:`pty`:
+
+ * ``master_open()``: use :func:`pty.openpty`.
+ * ``slave_open()``: use :func:`pty.openpty`.
+
+* :mod:`sqlite3`:
+
+ * :data:`~sqlite3.version` and :data:`~sqlite3.version_info`.
+
+ * :meth:`~sqlite3.Cursor.execute` and :meth:`~sqlite3.Cursor.executemany`
+ if :ref:`named placeholders ` are used and
+ *parameters* is a sequence instead of a :class:`dict`.
+
+ * date and datetime adapter, date and timestamp converter:
+ see the :mod:`sqlite3` documentation for suggested replacement recipes.
+
+* :class:`types.CodeType`: Accessing :attr:`~codeobject.co_lnotab` was
+ deprecated in :pep:`626`
+ since 3.10 and was planned to be removed in 3.12,
+ but it only got a proper :exc:`DeprecationWarning` in 3.12.
+ May be removed in 3.14.
+ (Contributed by Nikita Sobolev in :gh:`101866`.)
+
+* :mod:`typing`: :class:`~typing.ByteString`, deprecated since Python 3.9,
+ now causes a :exc:`DeprecationWarning` to be emitted when it is used.
+
+* :mod:`urllib`:
+ :class:`!urllib.parse.Quoter` is deprecated: it was not intended to be a
+ public API.
+ (Contributed by Gregory P. Smith in :gh:`88168`.)
diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst
new file mode 100644
index 00000000000000..69824a881ef8dd
--- /dev/null
+++ b/Doc/deprecations/pending-removal-in-3.15.rst
@@ -0,0 +1,57 @@
+Pending Removal in Python 3.15
+------------------------------
+
+* :class:`http.server.CGIHTTPRequestHandler` will be removed along with its
+ related ``--cgi`` flag to ``python -m http.server``. It was obsolete and
+ rarely used. No direct replacement exists. *Anything* is better than CGI
+ to interface a web server with a request handler.
+
+* :class:`locale`: :func:`locale.getdefaultlocale` was deprecated in Python 3.11
+ and originally planned for removal in Python 3.13 (:gh:`90817`),
+ but removal has been postponed to Python 3.15.
+ Use :func:`locale.setlocale()`, :func:`locale.getencoding()` and
+ :func:`locale.getlocale()` instead.
+ (Contributed by Hugo van Kemenade in :gh:`111187`.)
+
+* :mod:`pathlib`:
+ :meth:`pathlib.PurePath.is_reserved` is deprecated and scheduled for
+ removal in Python 3.15. From Python 3.13 onwards, use ``os.path.isreserved``
+ to detect reserved paths on Windows.
+
+* :mod:`platform`:
+ :func:`~platform.java_ver` is deprecated and will be removed in 3.15.
+ It was largely untested, had a confusing API,
+ and was only useful for Jython support.
+ (Contributed by Nikita Sobolev in :gh:`116349`.)
+
+* :mod:`threading`:
+ Passing any arguments to :func:`threading.RLock` is now deprecated.
+ C version allows any numbers of args and kwargs,
+ but they are just ignored. Python version does not allow any arguments.
+ All arguments will be removed from :func:`threading.RLock` in Python 3.15.
+ (Contributed by Nikita Sobolev in :gh:`102029`.)
+
+* :class:`typing.NamedTuple`:
+
+ * The undocumented keyword argument syntax for creating :class:`!NamedTuple` classes
+ (``NT = NamedTuple("NT", x=int)``) is deprecated, and will be disallowed in
+ 3.15. Use the class-based syntax or the functional syntax instead.
+
+ * When using the functional syntax to create a :class:`!NamedTuple` class, failing to
+ pass a value to the *fields* parameter (``NT = NamedTuple("NT")``) is
+ deprecated. Passing ``None`` to the *fields* parameter
+ (``NT = NamedTuple("NT", None)``) is also deprecated. Both will be
+ disallowed in Python 3.15. To create a :class:`!NamedTuple` class with 0 fields, use
+ ``class NT(NamedTuple): pass`` or ``NT = NamedTuple("NT", [])``.
+
+* :class:`typing.TypedDict`: When using the functional syntax to create a
+ :class:`!TypedDict` class, failing to pass a value to the *fields* parameter (``TD =
+ TypedDict("TD")``) is deprecated. Passing ``None`` to the *fields* parameter
+ (``TD = TypedDict("TD", None)``) is also deprecated. Both will be disallowed
+ in Python 3.15. To create a :class:`!TypedDict` class with 0 fields, use ``class
+ TD(TypedDict): pass`` or ``TD = TypedDict("TD", {})``.
+
+* :mod:`wave`: Deprecate the ``getmark()``, ``setmark()`` and ``getmarkers()``
+ methods of the :class:`wave.Wave_read` and :class:`wave.Wave_write` classes.
+ They will be removed in Python 3.15.
+ (Contributed by Victor Stinner in :gh:`105096`.)
diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst
new file mode 100644
index 00000000000000..10cb5e424a623b
--- /dev/null
+++ b/Doc/deprecations/pending-removal-in-3.16.rst
@@ -0,0 +1,10 @@
+Pending Removal in Python 3.16
+------------------------------
+
+* :mod:`array`:
+ :class:`array.array` ``'u'`` type (:c:type:`wchar_t`):
+ use the ``'w'`` type instead (``Py_UCS4``).
+
+* :mod:`symtable`:
+ Deprecate :meth:`symtable.Class.get_methods` due to the lack of interest.
+ (Contributed by Bénédikt Tran in :gh:`119698`.)
diff --git a/Doc/deprecations/pending-removal-in-future.rst b/Doc/deprecations/pending-removal-in-future.rst
new file mode 100644
index 00000000000000..7f10d9a98257f9
--- /dev/null
+++ b/Doc/deprecations/pending-removal-in-future.rst
@@ -0,0 +1,153 @@
+Pending Removal in Future Versions
+----------------------------------
+
+The following APIs will be removed in the future,
+although there is currently no date scheduled for their removal.
+
+* :mod:`argparse`: Nesting argument groups and nesting mutually exclusive
+ groups are deprecated.
+
+* :mod:`array`'s ``'u'`` format code (:gh:`57281`)
+
+* :mod:`builtins`:
+
+ * ``~bool``, bitwise inversion on bool.
+ * ``bool(NotImplemented)``.
+ * Generators: ``throw(type, exc, tb)`` and ``athrow(type, exc, tb)``
+ signature is deprecated: use ``throw(exc)`` and ``athrow(exc)`` instead,
+ the single argument signature.
+ * Currently Python accepts numeric literals immediately followed by keywords,
+ for example ``0in x``, ``1or x``, ``0if 1else 2``. It allows confusing and
+ ambiguous expressions like ``[0x1for x in y]`` (which can be interpreted as
+ ``[0x1 for x in y]`` or ``[0x1f or x in y]``). A syntax warning is raised
+ if the numeric literal is immediately followed by one of keywords
+ :keyword:`and`, :keyword:`else`, :keyword:`for`, :keyword:`if`,
+ :keyword:`in`, :keyword:`is` and :keyword:`or`. In a future release it
+ will be changed to a syntax error. (:gh:`87999`)
+ * Support for ``__index__()`` and ``__int__()`` method returning non-int type:
+ these methods will be required to return an instance of a strict subclass of
+ :class:`int`.
+ * Support for ``__float__()`` method returning a strict subclass of
+ :class:`float`: these methods will be required to return an instance of
+ :class:`float`.
+ * Support for ``__complex__()`` method returning a strict subclass of
+ :class:`complex`: these methods will be required to return an instance of
+ :class:`complex`.
+ * Delegation of ``int()`` to ``__trunc__()`` method.
+ * Passing a complex number as the *real* or *imag* argument in the
+ :func:`complex` constructor is now deprecated; it should only be passed
+ as a single positional argument.
+ (Contributed by Serhiy Storchaka in :gh:`109218`.)
+
+* :mod:`calendar`: ``calendar.January`` and ``calendar.February`` constants are
+ deprecated and replaced by :data:`calendar.JANUARY` and
+ :data:`calendar.FEBRUARY`.
+ (Contributed by Prince Roshan in :gh:`103636`.)
+
+* :attr:`codeobject.co_lnotab`: use the :meth:`codeobject.co_lines` method
+ instead.
+
+* :mod:`datetime`:
+
+ * :meth:`~datetime.datetime.utcnow`:
+ use ``datetime.datetime.now(tz=datetime.UTC)``.
+ * :meth:`~datetime.datetime.utcfromtimestamp`:
+ use ``datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)``.
+
+* :mod:`gettext`: Plural value must be an integer.
+
+* :mod:`importlib`:
+
+ * ``load_module()`` method: use ``exec_module()`` instead.
+ * :func:`~importlib.util.cache_from_source` *debug_override* parameter is
+ deprecated: use the *optimization* parameter instead.
+
+* :mod:`importlib.metadata`:
+
+ * ``EntryPoints`` tuple interface.
+ * Implicit ``None`` on return values.
+
+* :mod:`mailbox`: Use of StringIO input and text mode is deprecated, use
+ BytesIO and binary mode instead.
+
+* :mod:`os`: Calling :func:`os.register_at_fork` in multi-threaded process.
+
+* :class:`!pydoc.ErrorDuringImport`: A tuple value for *exc_info* parameter is
+ deprecated, use an exception instance.
+
+* :mod:`re`: More strict rules are now applied for numerical group references
+ and group names in regular expressions. Only sequence of ASCII digits is now
+ accepted as a numerical reference. The group name in bytes patterns and
+ replacement strings can now only contain ASCII letters and digits and
+ underscore.
+ (Contributed by Serhiy Storchaka in :gh:`91760`.)
+
+* :mod:`!sre_compile`, :mod:`!sre_constants` and :mod:`!sre_parse` modules.
+
+* :mod:`shutil`: :func:`~shutil.rmtree`'s *onerror* parameter is deprecated in
+ Python 3.12; use the *onexc* parameter instead.
+
+* :mod:`ssl` options and protocols:
+
+ * :class:`ssl.SSLContext` without protocol argument is deprecated.
+ * :class:`ssl.SSLContext`: :meth:`~ssl.SSLContext.set_npn_protocols` and
+ :meth:`!selected_npn_protocol` are deprecated: use ALPN
+ instead.
+ * ``ssl.OP_NO_SSL*`` options
+ * ``ssl.OP_NO_TLS*`` options
+ * ``ssl.PROTOCOL_SSLv3``
+ * ``ssl.PROTOCOL_TLS``
+ * ``ssl.PROTOCOL_TLSv1``
+ * ``ssl.PROTOCOL_TLSv1_1``
+ * ``ssl.PROTOCOL_TLSv1_2``
+ * ``ssl.TLSVersion.SSLv3``
+ * ``ssl.TLSVersion.TLSv1``
+ * ``ssl.TLSVersion.TLSv1_1``
+
+* :func:`sysconfig.is_python_build` *check_home* parameter is deprecated and
+ ignored.
+
+* :mod:`threading` methods:
+
+ * :meth:`!threading.Condition.notifyAll`: use :meth:`~threading.Condition.notify_all`.
+ * :meth:`!threading.Event.isSet`: use :meth:`~threading.Event.is_set`.
+ * :meth:`!threading.Thread.isDaemon`, :meth:`threading.Thread.setDaemon`:
+ use :attr:`threading.Thread.daemon` attribute.
+ * :meth:`!threading.Thread.getName`, :meth:`threading.Thread.setName`:
+ use :attr:`threading.Thread.name` attribute.
+ * :meth:`!threading.currentThread`: use :meth:`threading.current_thread`.
+ * :meth:`!threading.activeCount`: use :meth:`threading.active_count`.
+
+* :class:`typing.Text` (:gh:`92332`).
+
+* :class:`unittest.IsolatedAsyncioTestCase`: it is deprecated to return a value
+ that is not ``None`` from a test case.
+
+* :mod:`urllib.parse` deprecated functions: :func:`~urllib.parse.urlparse` instead
+
+ * ``splitattr()``
+ * ``splithost()``
+ * ``splitnport()``
+ * ``splitpasswd()``
+ * ``splitport()``
+ * ``splitquery()``
+ * ``splittag()``
+ * ``splittype()``
+ * ``splituser()``
+ * ``splitvalue()``
+ * ``to_bytes()``
+
+* :mod:`urllib.request`: :class:`~urllib.request.URLopener` and
+ :class:`~urllib.request.FancyURLopener` style of invoking requests is
+ deprecated. Use newer :func:`~urllib.request.urlopen` functions and methods.
+
+* :mod:`wsgiref`: ``SimpleHandler.stdout.write()`` should not do partial
+ writes.
+
+* :mod:`xml.etree.ElementTree`: Testing the truth value of an
+ :class:`~xml.etree.ElementTree.Element` is deprecated. In a future release it
+ will always return ``True``. Prefer explicit ``len(elem)`` or
+ ``elem is not None`` tests instead.
+
+* :meth:`zipimport.zipimporter.load_module` is deprecated:
+ use :meth:`~zipimport.zipimporter.exec_module` instead.
diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst
index c8beb64e39bc1a..ebb6d5ed1288c6 100644
--- a/Doc/faq/design.rst
+++ b/Doc/faq/design.rst
@@ -70,7 +70,7 @@ operations. This means that as far as floating-point operations are concerned,
Python behaves like many popular languages including C and Java.
Many numbers that can be written easily in decimal notation cannot be expressed
-exactly in binary floating-point. For example, after::
+exactly in binary floating point. For example, after::
>>> x = 1.2
@@ -87,7 +87,7 @@ which is exactly::
The typical precision of 53 bits provides Python floats with 15--16
decimal digits of accuracy.
-For a fuller explanation, please see the :ref:`floating point arithmetic
+For a fuller explanation, please see the :ref:`floating-point arithmetic
` chapter in the Python tutorial.
diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst
index ac10a04d50d531..45fd7eb1140b4e 100644
--- a/Doc/faq/library.rst
+++ b/Doc/faq/library.rst
@@ -825,12 +825,12 @@ is simple::
import random
random.random()
-This returns a random floating point number in the range [0, 1).
+This returns a random floating-point number in the range [0, 1).
There are also many other specialized generators in this module, such as:
* ``randrange(a, b)`` chooses an integer in the range [a, b).
-* ``uniform(a, b)`` chooses a floating point number in the range [a, b).
+* ``uniform(a, b)`` chooses a floating-point number in the range [a, b).
* ``normalvariate(mean, sdev)`` samples the normal (Gaussian) distribution.
Some higher-level functions operate on sequences directly, such as:
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index f43f69b8a1ea91..e5f8ebdfb9d1d9 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -869,7 +869,7 @@ How do I convert a string to a number?
--------------------------------------
For integers, use the built-in :func:`int` type constructor, e.g. ``int('144')
-== 144``. Similarly, :func:`float` converts to floating-point,
+== 144``. Similarly, :func:`float` converts to a floating-point number,
e.g. ``float('144') == 144.0``.
By default, these interpret the number as decimal, so that ``int('0144') ==
@@ -1741,11 +1741,31 @@ but effective way to define class private variables. Any identifier of the form
is textually replaced with ``_classname__spam``, where ``classname`` is the
current class name with any leading underscores stripped.
-This doesn't guarantee privacy: an outside user can still deliberately access
-the "_classname__spam" attribute, and private values are visible in the object's
-``__dict__``. Many Python programmers never bother to use private variable
-names at all.
+The identifier can be used unchanged within the class, but to access it outside
+the class, the mangled name must be used:
+.. code-block:: python
+
+ class A:
+ def __one(self):
+ return 1
+ def two(self):
+ return 2 * self.__one()
+
+ class B(A):
+ def three(self):
+ return 3 * self._A__one()
+
+ four = 4 * A()._A__one()
+
+In particular, this does not guarantee privacy since an outside user can still
+deliberately access the private attribute; many Python programmers never bother
+to use private variable names at all.
+
+.. seealso::
+
+ The :ref:`private name mangling specifications `
+ for details and special cases.
My class defines __del__ but it is not called when I delete the object.
-----------------------------------------------------------------------
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index 330402d1835711..7d1e4b7fa64631 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -787,7 +787,7 @@ Invocation from super
---------------------
The logic for super's dotted lookup is in the :meth:`__getattribute__` method for
-object returned by :class:`super()`.
+object returned by :func:`super`.
A dotted lookup such as ``super(A, obj).m`` searches ``obj.__class__.__mro__``
for the base class ``B`` immediately following ``A`` and then returns
diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst
index ffdafb749c73a9..04a1b3e41b7c06 100644
--- a/Doc/howto/enum.rst
+++ b/Doc/howto/enum.rst
@@ -1129,6 +1129,14 @@ the following are true:
>>> (Color.RED | Color.GREEN).name
'RED|GREEN'
+ >>> class Perm(IntFlag):
+ ... R = 4
+ ... W = 2
+ ... X = 1
+ ...
+ >>> (Perm.R & Perm.W).name is None # effectively Perm(0)
+ True
+
- multi-bit flags, aka aliases, can be returned from operations::
>>> Color.RED | Color.BLUE
diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst
index e35855deedbe5f..a636e06bda8344 100644
--- a/Doc/howto/isolating-extensions.rst
+++ b/Doc/howto/isolating-extensions.rst
@@ -339,7 +339,7 @@ That is, heap types should:
- Define a traverse function using ``Py_tp_traverse``, which
visits the type (e.g. using ``Py_VISIT(Py_TYPE(self))``).
-Please refer to the the documentation of
+Please refer to the documentation of
:c:macro:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse`
for additional considerations.
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 06a1ec18b0a331..c7b463d130346e 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -4022,7 +4022,7 @@ As you can see, this output isn't ideal. That's because the underlying code
which writes to ``sys.stderr`` makes multiple 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``:
+are seen. Let's use a slightly better implementation of ``LoggerWriter``:
.. code-block:: python
diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst
index 877cb24328c160..b96ff7fd20ee20 100644
--- a/Doc/howto/logging.rst
+++ b/Doc/howto/logging.rst
@@ -381,8 +381,48 @@ Logging Flow
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
+.. raw:: html
+ :file: logging_flow.svg
+
+.. raw:: html
+
+
Loggers
^^^^^^^
diff --git a/Doc/howto/logging_flow.png b/Doc/howto/logging_flow.png
index d65e597f811db5..d60ed7c031585a 100644
Binary files a/Doc/howto/logging_flow.png and b/Doc/howto/logging_flow.png differ
diff --git a/Doc/howto/logging_flow.svg b/Doc/howto/logging_flow.svg
new file mode 100644
index 00000000000000..4974994ac6b400
--- /dev/null
+++ b/Doc/howto/logging_flow.svg
@@ -0,0 +1,327 @@
+
diff --git a/Doc/library/__main__.rst b/Doc/library/__main__.rst
index 6232e173d9537d..647ff9da04d10d 100644
--- a/Doc/library/__main__.rst
+++ b/Doc/library/__main__.rst
@@ -251,9 +251,9 @@ attribute will include the package's path if imported::
>>> asyncio.__main__.__name__
'asyncio.__main__'
-This won't work for ``__main__.py`` files in the root directory of a .zip file
-though. Hence, for consistency, minimal ``__main__.py`` like the :mod:`venv`
-one mentioned below are preferred.
+This won't work for ``__main__.py`` files in the root directory of a
+``.zip`` file though. Hence, for consistency, a minimal ``__main__.py``
+without a ``__name__`` check is preferred.
.. seealso::
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index beaa8cdadda695..b4e656a7a83568 100644
--- a/Doc/library/array.rst
+++ b/Doc/library/array.rst
@@ -9,7 +9,7 @@
--------------
This module defines an object type which can compactly represent an array of
-basic values: characters, integers, floating point numbers. Arrays are sequence
+basic values: characters, integers, floating-point numbers. Arrays are sequence
types and behave very much like lists, except that the type of objects stored in
them is constrained. The type is specified at object creation time by using a
:dfn:`type code`, which is a single character. The following type codes are
@@ -253,7 +253,7 @@ The string representation is guaranteed to be able to be converted back to an
array with the same type and value using :func:`eval`, so long as the
:class:`~array.array` class has been imported using ``from array import array``.
Variables ``inf`` and ``nan`` must also be defined if it contains
-corresponding floating point values.
+corresponding floating-point values.
Examples::
array('l')
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 1c0c808e273258..28efafc6c46475 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -881,11 +881,15 @@ Statements
.. class:: AnnAssign(target, annotation, value, simple)
An assignment with a type annotation. ``target`` is a single node and can
- be a :class:`Name`, a :class:`Attribute` or a :class:`Subscript`.
+ be a :class:`Name`, an :class:`Attribute` or a :class:`Subscript`.
``annotation`` is the annotation, such as a :class:`Constant` or :class:`Name`
- node. ``value`` is a single optional node. ``simple`` is a boolean integer
- set to True for a :class:`Name` node in ``target`` that do not appear in
- between parenthesis and are hence pure names and not expressions.
+ node. ``value`` is a single optional node.
+
+ ``simple`` is always either 0 (indicating a "complex" target) or 1
+ (indicating a "simple" target). A "simple" target consists solely of a
+ :class:`Name` node that does not appear between parentheses; all other
+ targets are considered complex. Only simple targets appear in
+ the :attr:`__annotations__` dictionary of modules and classes.
.. doctest::
@@ -2000,7 +2004,7 @@ Function and class definitions
YieldFrom(value)
A ``yield`` or ``yield from`` expression. Because these are expressions, they
- must be wrapped in a :class:`Expr` node if the value sent back is not used.
+ must be wrapped in an :class:`Expr` node if the value sent back is not used.
.. doctest::
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index ba0ee1b6c2c528..2b6f7df10718a8 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -1139,6 +1139,14 @@ DNS
Asynchronous version of :meth:`socket.getnameinfo`.
+.. note::
+ Both *getaddrinfo* and *getnameinfo* internally utilize their synchronous
+ versions through the loop's default thread pool executor.
+ When this executor is saturated, these methods may experience delays,
+ which higher-level networking libraries may report as increased timeouts.
+ To mitigate this, consider using a custom executor for other user tasks,
+ or setting a default executor with a larger number of workers.
+
.. versionchanged:: 3.7
Both *getaddrinfo* and *getnameinfo* methods were always documented
to return a coroutine, but prior to Python 3.7 they were, in fact,
@@ -1238,6 +1246,9 @@ Executing code in thread or process pools
The *executor* argument should be an :class:`concurrent.futures.Executor`
instance. The default executor is used if *executor* is ``None``.
+ The default executor can be set by :meth:`loop.set_default_executor`,
+ otherwise, a :class:`concurrent.futures.ThreadPoolExecutor` will be
+ lazy-initialized and used by :func:`run_in_executor` if needed.
Example::
diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst
index 893ae5518f757d..9dce0731411940 100644
--- a/Doc/library/asyncio-future.rst
+++ b/Doc/library/asyncio-future.rst
@@ -120,20 +120,20 @@ Future Object
a :exc:`CancelledError` exception.
If the Future's result isn't yet available, this method raises
- a :exc:`InvalidStateError` exception.
+ an :exc:`InvalidStateError` exception.
.. method:: set_result(result)
Mark the Future as *done* and set its result.
- Raises a :exc:`InvalidStateError` error if the Future is
+ Raises an :exc:`InvalidStateError` error if the Future is
already *done*.
.. method:: set_exception(exception)
Mark the Future as *done* and set an exception.
- Raises a :exc:`InvalidStateError` error if the Future is
+ Raises an :exc:`InvalidStateError` error if the Future is
already *done*.
.. method:: done()
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index 6c046ebec961e4..48cd2f247adce9 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -1104,7 +1104,7 @@ Task Object
a :exc:`CancelledError` exception.
If the Task's result isn't yet available, this method raises
- a :exc:`InvalidStateError` exception.
+ an :exc:`InvalidStateError` exception.
.. method:: exception()
diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst
index 184f981c1021aa..1fb575d77f3e17 100644
--- a/Doc/library/asyncio.rst
+++ b/Doc/library/asyncio.rst
@@ -56,8 +56,12 @@ Additionally, there are **low-level** APIs for
* :ref:`bridge ` callback-based libraries and code
with async/await syntax.
+.. include:: ../includes/wasm-notavail.rst
+
.. _asyncio-cli:
+.. rubric:: asyncio REPL
+
You can experiment with an ``asyncio`` concurrent context in the REPL:
.. code-block:: pycon
@@ -70,7 +74,10 @@ You can experiment with an ``asyncio`` concurrent context in the REPL:
>>> await asyncio.sleep(10, result='hello')
'hello'
-.. include:: ../includes/wasm-notavail.rst
+.. audit-event:: cpython.run_stdin "" ""
+
+.. versionchanged:: 3.12.5 (also 3.11.10, 3.10.15, 3.9.20, and 3.8.20)
+ Emits audit events.
.. We use the "rubric" directive here to avoid creating
the "Reference" subsection in the TOC.
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index fedf1914145aa0..fe9a35ecfb0c7c 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -99,7 +99,7 @@ The class can be used to simulate nested scopes and is useful in templating.
:func:`super` function. A reference to ``d.parents`` is equivalent to:
``ChainMap(*d.maps[1:])``.
- Note, the iteration order of a :class:`ChainMap()` is determined by
+ Note, the iteration order of a :class:`ChainMap` is determined by
scanning the mappings last to first::
>>> baseline = {'music': 'bach', 'art': 'rembrandt'}
diff --git a/Doc/library/colorsys.rst b/Doc/library/colorsys.rst
index 125d62b174088a..ffebf4e40dd609 100644
--- a/Doc/library/colorsys.rst
+++ b/Doc/library/colorsys.rst
@@ -14,7 +14,7 @@ The :mod:`colorsys` module defines bidirectional conversions of color values
between colors expressed in the RGB (Red Green Blue) color space used in
computer monitors and three other coordinate systems: YIQ, HLS (Hue Lightness
Saturation) and HSV (Hue Saturation Value). Coordinates in all of these color
-spaces are floating point values. In the YIQ space, the Y coordinate is between
+spaces are floating-point values. In the YIQ space, the Y coordinate is between
0 and 1, but the I and Q coordinates can be positive or negative. In all other
spaces, the coordinates are all between 0 and 1.
diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst
index 560260e8a4b971..573a23b312c500 100644
--- a/Doc/library/configparser.rst
+++ b/Doc/library/configparser.rst
@@ -147,23 +147,28 @@ case-insensitive and stored in lowercase [1]_.
It is possible to read several configurations into a single
:class:`ConfigParser`, where the most recently added configuration has the
highest priority. Any conflicting keys are taken from the more recent
-configuration while the previously existing keys are retained.
+configuration while the previously existing keys are retained. The example
+below reads in an ``override.ini`` file, which will override any conflicting
+keys from the ``example.ini`` file.
+
+.. code-block:: ini
+
+ [DEFAULT]
+ ServerAliveInterval = -1
.. doctest::
- >>> another_config = configparser.ConfigParser()
- >>> another_config.read('example.ini')
- ['example.ini']
- >>> another_config['topsecret.server.example']['Port']
- '50022'
- >>> another_config.read_string("[topsecret.server.example]\nPort=48484")
- >>> another_config['topsecret.server.example']['Port']
- '48484'
- >>> another_config.read_dict({"topsecret.server.example": {"Port": 21212}})
- >>> another_config['topsecret.server.example']['Port']
- '21212'
- >>> another_config['topsecret.server.example']['ForwardX11']
- 'no'
+ >>> config_override = configparser.ConfigParser()
+ >>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
+ >>> with open('override.ini', 'w') as configfile:
+ ... config_override.write(configfile)
+ ...
+ >>> config_override = configparser.ConfigParser()
+ >>> config_override.read(['example.ini', 'override.ini'])
+ ['example.ini', 'override.ini']
+ >>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
+ -1
+
This behaviour is equivalent to a :meth:`ConfigParser.read` call with several
files passed to the *filenames* parameter.
@@ -958,6 +963,31 @@ ConfigParser Objects
converter gets its own corresponding :meth:`!get*()` method on the parser
object and section proxies.
+ It is possible to read several configurations into a single
+ :class:`ConfigParser`, where the most recently added configuration has the
+ highest priority. Any conflicting keys are taken from the more recent
+ configuration while the previously existing keys are retained. The example
+ below reads in an ``override.ini`` file, which will override any conflicting
+ keys from the ``example.ini`` file.
+
+ .. code-block:: ini
+
+ [DEFAULT]
+ ServerAliveInterval = -1
+
+ .. doctest::
+
+ >>> config_override = configparser.ConfigParser()
+ >>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
+ >>> with open('override.ini', 'w') as configfile:
+ ... config_override.write(configfile)
+ ...
+ >>> config_override = configparser.ConfigParser()
+ >>> config_override.read(['example.ini', 'override.ini'])
+ ['example.ini', 'override.ini']
+ >>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
+ -1
+
.. versionchanged:: 3.1
The default *dict_type* is :class:`collections.OrderedDict`.
@@ -1123,7 +1153,7 @@ ConfigParser Objects
.. method:: getfloat(section, option, *, raw=False, vars=None[, fallback])
A convenience method which coerces the *option* in the specified *section*
- to a floating point number. See :meth:`get` for explanation of *raw*,
+ to a floating-point number. See :meth:`get` for explanation of *raw*,
*vars* and *fallback*.
diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst
index 27cf99446e5980..f5b349441bcfee 100644
--- a/Doc/library/contextlib.rst
+++ b/Doc/library/contextlib.rst
@@ -322,7 +322,7 @@ Functions and classes provided:
.. versionchanged:: 3.12
``suppress`` now supports suppressing exceptions raised as
- part of an :exc:`BaseExceptionGroup`.
+ part of a :exc:`BaseExceptionGroup`.
.. function:: redirect_stdout(new_target)
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index e01bd9277b19d3..130f9b9cab4eaa 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -107,7 +107,7 @@ Functions are accessed as attributes of dll objects::
Note that win32 system dlls like ``kernel32`` and ``user32`` often export ANSI
as well as UNICODE versions of a function. The UNICODE version is exported with
-an ``W`` appended to the name, while the ANSI version is exported with an ``A``
+a ``W`` appended to the name, while the ANSI version is exported with an ``A``
appended to the name. The win32 ``GetModuleHandle`` function, which returns a
*module handle* for a given module name, has the following C prototype, and a
macro is used to expose one of them as ``GetModuleHandle`` depending on whether
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index 4ba9d6df890f29..1109dac9afa065 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -48,7 +48,7 @@ Aware and Naive Objects
-----------------------
Date and time objects may be categorized as "aware" or "naive" depending on
-whether or not they include timezone information.
+whether or not they include time zone information.
With sufficient knowledge of applicable algorithmic and political time
adjustments, such as time zone and daylight saving time information,
@@ -58,7 +58,7 @@ interpretation. [#]_
A **naive** object does not contain enough information to unambiguously locate
itself relative to other date/time objects. Whether a naive object represents
-Coordinated Universal Time (UTC), local time, or time in some other timezone is
+Coordinated Universal Time (UTC), local time, or time in some other time zone is
purely up to the program, just like it is up to the program whether a
particular number represents metres, miles, or mass. Naive objects are easy to
understand and to work with, at the cost of ignoring some aspects of reality.
@@ -70,9 +70,9 @@ These :class:`tzinfo` objects capture information about the offset from UTC
time, the time zone name, and whether daylight saving time is in effect.
Only one concrete :class:`tzinfo` class, the :class:`timezone` class, is
-supplied by the :mod:`!datetime` module. The :class:`timezone` class can
-represent simple timezones with fixed offsets from UTC, such as UTC itself or
-North American EST and EDT timezones. Supporting timezones at deeper levels of
+supplied by the :mod:`!datetime` module. The :class:`!timezone` class can
+represent simple time zones with fixed offsets from UTC, such as UTC itself or
+North American EST and EDT time zones. Supporting time zones at deeper levels of
detail is up to the application. The rules for time adjustment across the
world are more political than rational, change frequently, and there is no
standard suitable for every application aside from UTC.
@@ -95,7 +95,7 @@ The :mod:`!datetime` module exports the following constants:
.. attribute:: UTC
- Alias for the UTC timezone singleton :attr:`datetime.timezone.utc`.
+ Alias for the UTC time zone singleton :attr:`datetime.timezone.utc`.
.. versionadded:: 3.11
@@ -850,7 +850,7 @@ Other constructors, all class methods:
.. classmethod:: datetime.today()
- Return the current local datetime, with :attr:`.tzinfo` ``None``.
+ Return the current local date and time, with :attr:`.tzinfo` ``None``.
Equivalent to::
@@ -1051,7 +1051,7 @@ Other constructors, all class methods:
Return a :class:`.datetime` corresponding to *date_string*, parsed according to
*format*.
- If *format* does not contain microseconds or timezone information, this is equivalent to::
+ If *format* does not contain microseconds or time zone information, this is equivalent to::
datetime(*(time.strptime(date_string, format)[0:6]))
@@ -1267,22 +1267,22 @@ Instance methods:
If provided, *tz* must be an instance of a :class:`tzinfo` subclass, and its
:meth:`utcoffset` and :meth:`dst` methods must not return ``None``. If *self*
- is naive, it is presumed to represent time in the system timezone.
+ is naive, it is presumed to represent time in the system time zone.
If called without arguments (or with ``tz=None``) the system local
- timezone is assumed for the target timezone. The ``.tzinfo`` attribute of the converted
+ time zone is assumed for the target time zone. The ``.tzinfo`` attribute of the converted
datetime instance will be set to an instance of :class:`timezone`
with the zone name and offset obtained from the OS.
If ``self.tzinfo`` is *tz*, ``self.astimezone(tz)`` is equal to *self*: no
adjustment of date or time data is performed. Else the result is local
- time in the timezone *tz*, representing the same UTC time as *self*: after
+ time in the time zone *tz*, representing the same UTC time as *self*: after
``astz = dt.astimezone(tz)``, ``astz - astz.utcoffset()`` will have
the same date and time data as ``dt - dt.utcoffset()``.
- If you merely want to attach a time zone object *tz* to a datetime *dt* without
+ If you merely want to attach a :class:`timezone` object *tz* to a datetime *dt* without
adjustment of date and time data, use ``dt.replace(tzinfo=tz)``. If you
- merely want to remove the time zone object from an aware datetime *dt* without
+ merely want to remove the :class:`!timezone` object from an aware datetime *dt* without
conversion of date and time data, use ``dt.replace(tzinfo=None)``.
Note that the default :meth:`tzinfo.fromutc` method can be overridden in a
@@ -1292,7 +1292,7 @@ Instance methods:
def astimezone(self, tz):
if self.tzinfo is tz:
return self
- # Convert self to UTC, and attach the new time zone object.
+ # Convert self to UTC, and attach the new timezone object.
utc = (self - self.utcoffset()).replace(tzinfo=tz)
# Convert from UTC to tz's local time.
return tz.fromutc(utc)
@@ -1406,7 +1406,7 @@ Instance methods:
There is no method to obtain the POSIX timestamp directly from a
naive :class:`.datetime` instance representing UTC time. If your
- application uses this convention and your system timezone is not
+ application uses this convention and your system time zone is not
set to UTC, you can obtain the POSIX timestamp by supplying
``tzinfo=timezone.utc``::
@@ -1974,7 +1974,7 @@ Examples of working with a :class:`.time` object::
supply implementations of the standard :class:`tzinfo` methods needed by the
:class:`.datetime` methods you use. The :mod:`!datetime` module provides
:class:`timezone`, a simple concrete subclass of :class:`tzinfo` which can
- represent timezones with fixed offset from UTC such as UTC itself or North
+ represent time zones with fixed offset from UTC such as UTC itself or North
American EST and EDT.
Special requirement for pickling: A :class:`tzinfo` subclass must have an
@@ -2099,14 +2099,14 @@ When a :class:`.datetime` object is passed in response to a :class:`.datetime`
method, ``dt.tzinfo`` is the same object as *self*. :class:`tzinfo` methods can
rely on this, unless user code calls :class:`tzinfo` methods directly. The
intent is that the :class:`tzinfo` methods interpret *dt* as being in local
-time, and not need worry about objects in other timezones.
+time, and not need worry about objects in other time zones.
There is one more :class:`tzinfo` method that a subclass may wish to override:
.. method:: tzinfo.fromutc(dt)
- This is called from the default :class:`datetime.astimezone()`
+ This is called from the default :meth:`datetime.astimezone`
implementation. When called from that, ``dt.tzinfo`` is *self*, and *dt*'s
date and time data are to be viewed as expressing a UTC time. The purpose
of :meth:`fromutc` is to adjust the date and time data, returning an
@@ -2216,12 +2216,12 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
:mod:`zoneinfo`
The :mod:`!datetime` module has a basic :class:`timezone` class (for
handling arbitrary fixed offsets from UTC) and its :attr:`timezone.utc`
- attribute (a UTC timezone instance).
+ attribute (a UTC :class:`!timezone` instance).
- ``zoneinfo`` brings the *IANA timezone database* (also known as the Olson
+ ``zoneinfo`` brings the *IANA time zone database* (also known as the Olson
database) to Python, and its usage is recommended.
- `IANA timezone database `_
+ `IANA time zone database `_
The Time Zone Database (often called tz, tzdata or zoneinfo) contains code
and data that represent the history of local time for many representative
locations around the globe. It is updated periodically to reflect changes
@@ -2235,10 +2235,10 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
-------------------------
The :class:`timezone` class is a subclass of :class:`tzinfo`, each
-instance of which represents a timezone defined by a fixed offset from
+instance of which represents a time zone defined by a fixed offset from
UTC.
-Objects of this class cannot be used to represent timezone information in the
+Objects of this class cannot be used to represent time zone information in the
locations where different offsets are used in different days of the year or
where historical changes have been made to civil time.
@@ -2299,7 +2299,7 @@ Class attributes:
.. attribute:: timezone.utc
- The UTC timezone, ``timezone(timedelta(0))``.
+ The UTC time zone, ``timezone(timedelta(0))``.
.. index::
@@ -2508,7 +2508,7 @@ Using ``datetime.strptime(date_string, format)`` is equivalent to::
datetime(*(time.strptime(date_string, format)[0:6]))
-except when the format includes sub-second components or timezone offset
+except when the format includes sub-second components or time zone offset
information, which are supported in ``datetime.strptime`` but are discarded by
``time.strptime``.
diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index 9aa4254ab80427..c5544f6216fd7b 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -1,4 +1,4 @@
-:mod:`!decimal` --- Decimal fixed point and floating point arithmetic
+:mod:`!decimal` --- Decimal fixed-point and floating-point arithmetic
=====================================================================
.. module:: decimal
@@ -31,7 +31,7 @@
--------------
The :mod:`decimal` module provides support for fast correctly rounded
-decimal floating point arithmetic. It offers several advantages over the
+decimal floating-point arithmetic. It offers several advantages over the
:class:`float` datatype:
* Decimal "is based on a floating-point model which was designed with people
@@ -207,7 +207,7 @@ a decimal raises :class:`InvalidOperation`::
.. versionchanged:: 3.3
Decimals interact well with much of the rest of Python. Here is a small decimal
-floating point flying circus:
+floating-point flying circus:
.. doctest::
:options: +NORMALIZE_WHITESPACE
@@ -373,7 +373,7 @@ Decimal objects
digits, and an integer exponent. For example, ``Decimal((0, (1, 4, 1, 4), -3))``
returns ``Decimal('1.414')``.
- If *value* is a :class:`float`, the binary floating point value is losslessly
+ If *value* is a :class:`float`, the binary floating-point value is losslessly
converted to its exact decimal equivalent. This conversion can often require
53 or more digits of precision. For example, ``Decimal(float('1.1'))``
converts to
@@ -403,7 +403,7 @@ Decimal objects
Underscores are allowed for grouping, as with integral and floating-point
literals in code.
- Decimal floating point objects share many properties with the other built-in
+ Decimal floating-point objects share many properties with the other built-in
numeric types such as :class:`float` and :class:`int`. All of the usual math
operations and special methods apply. Likewise, decimal objects can be
copied, pickled, printed, used as dictionary keys, used as set elements,
@@ -445,7 +445,7 @@ Decimal objects
Mixed-type comparisons between :class:`Decimal` instances and other
numeric types are now fully supported.
- In addition to the standard numeric properties, decimal floating point
+ In addition to the standard numeric properties, decimal floating-point
objects also have a number of specialized methods:
@@ -897,6 +897,48 @@ Decimal objects
:const:`Rounded`. If given, applies *rounding*; otherwise, uses the
rounding method in either the supplied *context* or the current context.
+ Decimal numbers can be rounded using the :func:`.round` function:
+
+ .. describe:: round(number)
+ .. describe:: round(number, ndigits)
+
+ If *ndigits* is not given or ``None``,
+ returns the nearest :class:`int` to *number*,
+ rounding ties to even, and ignoring the rounding mode of the
+ :class:`Decimal` context. Raises :exc:`OverflowError` if *number* is an
+ infinity or :exc:`ValueError` if it is a (quiet or signaling) NaN.
+
+ If *ndigits* is an :class:`int`, the context's rounding mode is respected
+ and a :class:`Decimal` representing *number* rounded to the nearest
+ multiple of ``Decimal('1E-ndigits')`` is returned; in this case,
+ ``round(number, ndigits)`` is equivalent to
+ ``self.quantize(Decimal('1E-ndigits'))``. Returns ``Decimal('NaN')`` if
+ *number* is a quiet NaN. Raises :class:`InvalidOperation` if *number*
+ is an infinity, a signaling NaN, or if the length of the coefficient after
+ the quantize operation would be greater than the current context's
+ precision. In other words, for the non-corner cases:
+
+ * if *ndigits* is positive, return *number* rounded to *ndigits* decimal
+ places;
+ * if *ndigits* is zero, return *number* rounded to the nearest integer;
+ * if *ndigits* is negative, return *number* rounded to the nearest
+ multiple of ``10**abs(ndigits)``.
+
+ For example::
+
+ >>> from decimal import Decimal, getcontext, ROUND_DOWN
+ >>> getcontext().rounding = ROUND_DOWN
+ >>> round(Decimal('3.75')) # context rounding ignored
+ 4
+ >>> round(Decimal('3.5')) # round-ties-to-even
+ 4
+ >>> round(Decimal('3.75'), 0) # uses the context rounding
+ Decimal('3')
+ >>> round(Decimal('3.75'), 1)
+ Decimal('3.7')
+ >>> round(Decimal('3.75'), -1)
+ Decimal('0E+1')
+
.. _logical_operands_label:
@@ -1699,7 +1741,7 @@ The following table summarizes the hierarchy of signals::
.. _decimal-notes:
-Floating Point Notes
+Floating-Point Notes
--------------------
@@ -1712,7 +1754,7 @@ can still incur round-off error when non-zero digits exceed the fixed precision.
The effects of round-off error can be amplified by the addition or subtraction
of nearly offsetting quantities resulting in loss of significance. Knuth
-provides two instructive examples where rounded floating point arithmetic with
+provides two instructive examples where rounded floating-point arithmetic with
insufficient precision causes the breakdown of the associative and distributive
properties of addition:
@@ -1802,7 +1844,7 @@ treated as equal and their sign is informational.
In addition to the two signed zeros which are distinct yet equal, there are
various representations of zero with differing precisions yet equivalent in
value. This takes a bit of getting used to. For an eye accustomed to
-normalized floating point representations, it is not immediately obvious that
+normalized floating-point representations, it is not immediately obvious that
the following calculation returns a value equal to zero:
>>> 1 / Decimal('Infinity')
@@ -2129,7 +2171,7 @@ value unchanged:
Q. Is there a way to convert a regular float to a :class:`Decimal`?
-A. Yes, any binary floating point number can be exactly expressed as a
+A. Yes, any binary floating-point number can be exactly expressed as a
Decimal though an exact conversion may take more precision than intuition would
suggest:
@@ -2183,7 +2225,7 @@ Q. Is the CPython implementation fast for large numbers?
A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of
the decimal module integrate the high speed `libmpdec
`_ library for
-arbitrary precision correctly rounded decimal floating point arithmetic [#]_.
+arbitrary precision correctly rounded decimal floating-point arithmetic [#]_.
``libmpdec`` uses `Karatsuba multiplication
`_
for medium-sized numbers and the `Number Theoretic Transform
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index e3920587099238..9414bee71880bb 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -995,11 +995,15 @@ iterations of the loop.
.. opcode:: BUILD_TUPLE (count)
Creates a tuple consuming *count* items from the stack, and pushes the
- resulting tuple onto the stack.::
+ resulting tuple onto the stack::
- assert count > 0
- STACK, values = STACK[:-count], STACK[-count:]
- STACK.append(tuple(values))
+ if count == 0:
+ value = ()
+ else:
+ STACK = STACK[:-count]
+ value = tuple(STACK[-count:])
+
+ STACK.append(value)
.. opcode:: BUILD_LIST (count)
@@ -1128,7 +1132,10 @@ iterations of the loop.
.. opcode:: COMPARE_OP (opname)
Performs a Boolean operation. The operation name can be found in
- ``cmp_op[opname]``.
+ ``cmp_op[opname >> 4]``.
+
+ .. versionchanged:: 3.12
+ The cmp_op index is now stored in the four-highest bits of oparg instead of the four-lowest bits of oparg.
.. opcode:: IS_OP (invert)
@@ -1592,7 +1599,7 @@ iterations of the loop.
| ``INTRINSIC_STOPITERATION_ERROR`` | Extracts the return value from a |
| | ``StopIteration`` exception. |
+-----------------------------------+-----------------------------------+
- | ``INTRINSIC_ASYNC_GEN_WRAP`` | Wraps an aync generator value |
+ | ``INTRINSIC_ASYNC_GEN_WRAP`` | Wraps an async generator value |
+-----------------------------------+-----------------------------------+
| ``INTRINSIC_UNARY_POSITIVE`` | Performs the unary ``+`` |
| | operation |
diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst
index c4c322a82e1f44..6e27a6e224a733 100644
--- a/Doc/library/email.compat32-message.rst
+++ b/Doc/library/email.compat32-message.rst
@@ -7,6 +7,7 @@
:synopsis: The base class representing email messages in a fashion
backward compatible with Python 3.2
:noindex:
+ :no-index:
The :class:`Message` class is very similar to the
diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst
index 33ab4265116178..f8f43d82a3df2e 100644
--- a/Doc/library/email.errors.rst
+++ b/Doc/library/email.errors.rst
@@ -58,6 +58,13 @@ The following exception classes are defined in the :mod:`email.errors` module:
:class:`~email.mime.nonmultipart.MIMENonMultipart` (e.g.
:class:`~email.mime.image.MIMEImage`).
+
+.. exception:: HeaderWriteError()
+
+ Raised when an error occurs when the :mod:`~email.generator` outputs
+ headers.
+
+
.. exception:: MessageDefect()
This is the base class for all defects found when parsing email messages.
diff --git a/Doc/library/email.header.rst b/Doc/library/email.header.rst
index 6e230d5faf1654..219fad0d2f6745 100644
--- a/Doc/library/email.header.rst
+++ b/Doc/library/email.header.rst
@@ -77,7 +77,7 @@ Here is the :class:`Header` class description:
The maximum line length can be specified explicitly via *maxlinelen*. For
splitting the first line to a shorter value (to account for the field header
which isn't included in *s*, e.g. :mailheader:`Subject`) pass in the name of the
- field in *header_name*. The default *maxlinelen* is 76, and the default value
+ field in *header_name*. The default *maxlinelen* is 78, and the default value
for *header_name* is ``None``, meaning it is not taken into account for the
first line of a long, split header.
diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst
index 83feedf728351e..51d65dc5ba94ee 100644
--- a/Doc/library/email.policy.rst
+++ b/Doc/library/email.policy.rst
@@ -229,6 +229,24 @@ added matters. To illustrate::
.. versionadded:: 3.6
+
+ .. attribute:: verify_generated_headers
+
+ If ``True`` (the default), the generator will raise
+ :exc:`~email.errors.HeaderWriteError` instead of writing a header
+ that is improperly folded or delimited, such that it would
+ be parsed as multiple headers or joined with adjacent data.
+ Such headers can be generated by custom header classes or bugs
+ in the ``email`` module.
+
+ As it's a security feature, this defaults to ``True`` even in the
+ :class:`~email.policy.Compat32` policy.
+ For backwards compatible, but unsafe, behavior, it must be set to
+ ``False`` explicitly.
+
+ .. versionadded:: 3.12.5
+
+
The following :class:`Policy` method is intended to be called by code using
the email library to create policy instances with custom settings:
diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst
index 092bfa8146206b..6ba42491d66601 100644
--- a/Doc/library/email.utils.rst
+++ b/Doc/library/email.utils.rst
@@ -148,7 +148,7 @@ of the new API.
Fri, 09 Nov 2001 01:08:47 -0000
- Optional *timeval* if given is a floating point time value as accepted by
+ Optional *timeval* if given is a floating-point time value as accepted by
:func:`time.gmtime` and :func:`time.localtime`, otherwise the current time is
used.
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
index 10acff619f91e0..3d0747bf5c7faf 100644
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -517,7 +517,7 @@ Data Types
``Flag`` is the same as :class:`Enum`, but its members support the bitwise
operators ``&`` (*AND*), ``|`` (*OR*), ``^`` (*XOR*), and ``~`` (*INVERT*);
- the results of those operators are members of the enumeration.
+ the results of those operations are (aliases of) members of the enumeration.
.. method:: __contains__(self, value)
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index de46518e673763..537547f6c9c5ca 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -412,8 +412,8 @@ The following exceptions are the exceptions that are usually raised.
represented. This cannot occur for integers (which would rather raise
:exc:`MemoryError` than give up). However, for historical reasons,
OverflowError is sometimes raised for integers that are outside a required
- range. Because of the lack of standardization of floating point exception
- handling in C, most floating point operations are not checked.
+ range. Because of the lack of standardization of floating-point exception
+ handling in C, most floating-point operations are not checked.
.. exception:: RecursionError
diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst
index 94a4139f64c2e4..8f32b11e565365 100644
--- a/Doc/library/fileinput.rst
+++ b/Doc/library/fileinput.rst
@@ -47,7 +47,7 @@ Lines are returned with any newlines intact, which means that the last line in
a file may not have one.
You can control how files are opened by providing an opening hook via the
-*openhook* parameter to :func:`fileinput.input` or :class:`FileInput()`. The
+*openhook* parameter to :func:`fileinput.input` or :func:`FileInput`. The
hook must be a function that takes two arguments, *filename* and *mode*, and
returns an accordingly opened file-like object. If *encoding* and/or *errors*
are specified, they will be passed to the hook as additional keyword arguments.
diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst
index 42569ec8e65aac..11591cb348d1c0 100644
--- a/Doc/library/fractions.rst
+++ b/Doc/library/fractions.rst
@@ -31,7 +31,7 @@ another rational number, or from a string.
:class:`Fraction` instance with the same value. The next two versions accept
either a :class:`float` or a :class:`decimal.Decimal` instance, and return a
:class:`Fraction` instance with exactly the same value. Note that due to the
- usual issues with binary floating-point (see :ref:`tut-fp-issues`), the
+ usual issues with binary floating point (see :ref:`tut-fp-issues`), the
argument to ``Fraction(1.1)`` is not exactly equal to 11/10, and so
``Fraction(1.1)`` does *not* return ``Fraction(11, 10)`` as one might expect.
(But see the documentation for the :meth:`limit_denominator` method below.)
@@ -87,7 +87,7 @@ another rational number, or from a string.
.. versionchanged:: 3.9
The :func:`math.gcd` function is now used to normalize the *numerator*
- and *denominator*. :func:`math.gcd` always return a :class:`int` type.
+ and *denominator*. :func:`math.gcd` always returns an :class:`int` type.
Previously, the GCD type depended on *numerator* and *denominator*.
.. versionchanged:: 3.11
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index 8c39dc00f5db02..bb15322067245e 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -243,7 +243,7 @@ FTP objects
Retrieve a file in binary transfer mode.
:param str cmd:
- An appropriate ``STOR`` command: :samp:`"STOR {filename}"`.
+ An appropriate ``RETR`` command: :samp:`"RETR {filename}"`.
:param callback:
A single parameter callable that is called
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 6901c021d7bd6e..2c3afb7ee1e8a1 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -57,7 +57,7 @@ are always available. They are listed here in alphabetical order.
.. function:: abs(x)
Return the absolute value of a number. The argument may be an
- integer, a floating point number, or an object implementing
+ integer, a floating-point number, or an object implementing
:meth:`~object.__abs__`.
If the argument is a complex number, its magnitude is returned.
@@ -538,7 +538,7 @@ are always available. They are listed here in alphabetical order.
Take two (non-complex) numbers as arguments and return a pair of numbers
consisting of their quotient and remainder when using integer division. With
mixed operand types, the rules for binary arithmetic operators apply. For
- integers, the result is the same as ``(a // b, a % b)``. For floating point
+ integers, the result is the same as ``(a // b, a % b)``. For floating-point
numbers the result is ``(q, a % b)``, where *q* is usually ``math.floor(a /
b)`` but may be 1 less than that. In any case ``q * b + a % b`` is very
close to *a*, if ``a % b`` is non-zero it has the same sign as *b*, and ``0
@@ -714,7 +714,7 @@ are always available. They are listed here in alphabetical order.
single: NaN
single: Infinity
- Return a floating point number constructed from a number or a string.
+ Return a floating-point number constructed from a number or a string.
Examples:
@@ -755,8 +755,8 @@ are always available. They are listed here in alphabetical order.
Case is not significant, so, for example, "inf", "Inf", "INFINITY", and
"iNfINity" are all acceptable spellings for positive infinity.
- Otherwise, if the argument is an integer or a floating point number, a
- floating point number with the same value (within Python's floating point
+ Otherwise, if the argument is an integer or a floating-point number, a
+ floating-point number with the same value (within Python's floating-point
precision) is returned. If the argument is outside the range of a Python
float, an :exc:`OverflowError` will be raised.
@@ -983,7 +983,7 @@ are always available. They are listed here in alphabetical order.
``int(x)`` returns ``x.__int__()``. If the argument defines :meth:`~object.__index__`,
it returns ``x.__index__()``. If the argument defines :meth:`~object.__trunc__`,
it returns ``x.__trunc__()``.
- For floating point numbers, this truncates towards zero.
+ For floating-point numbers, this truncates towards zero.
If the argument is not a number or if *base* is given, then it must be a string,
:class:`bytes`, or :class:`bytearray` instance representing an integer
@@ -1440,7 +1440,7 @@ are always available. They are listed here in alphabetical order.
(where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`,
and :mod:`shutil`.
- .. audit-event:: open file,mode,flags open
+ .. audit-event:: open path,mode,flags open
The ``mode`` and ``flags`` arguments may have been modified or inferred from
the original call.
@@ -1496,7 +1496,9 @@ are always available. They are listed here in alphabetical order.
returns ``100``, but ``pow(10, -2)`` returns ``0.01``. For a negative base of
type :class:`int` or :class:`float` and a non-integral exponent, a complex
result is delivered. For example, ``pow(-9, 0.5)`` returns a value close
- to ``3j``.
+ to ``3j``. Whereas, for a negative base of type :class:`int` or :class:`float`
+ with an integral exponent, a float result is delivered. For example,
+ ``pow(-9, 2.0)`` returns ``81.0``.
For :class:`int` operands *base* and *exp*, if *mod* is present, *mod* must
also be of integer type and *mod* must be nonzero. If *mod* is present and
@@ -1857,7 +1859,7 @@ are always available. They are listed here in alphabetical order.
For some use cases, there are good alternatives to :func:`sum`.
The preferred, fast way to concatenate a sequence of strings is by calling
- ``''.join(sequence)``. To add floating point values with extended precision,
+ ``''.join(sequence)``. To add floating-point values with extended precision,
see :func:`math.fsum`\. To concatenate a series of iterables, consider using
:func:`itertools.chain`.
diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst
index a2fff0f9fcb3e5..3008866671608a 100644
--- a/Doc/library/gzip.rst
+++ b/Doc/library/gzip.rst
@@ -194,7 +194,9 @@ The module defines the following items:
.. versionchanged:: 3.11
Speed is improved by compressing all data at once instead of in a
streamed fashion. Calls with *mtime* set to ``0`` are delegated to
- :func:`zlib.compress` for better speed.
+ :func:`zlib.compress` for better speed. In this situation the
+ output may contain a gzip header "OS" byte value other than 255
+ "unknown" as supplied by the underlying zlib implementation.
.. function:: decompress(data)
diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst
index fcc314a8d88892..a173795bd2867e 100644
--- a/Doc/library/http.server.rst
+++ b/Doc/library/http.server.rst
@@ -378,7 +378,7 @@ provides three different variants:
If the request was mapped to a file, it is opened. Any :exc:`OSError`
exception in opening the requested file is mapped to a ``404``,
- ``'File not found'`` error. If there was a ``'If-Modified-Since'``
+ ``'File not found'`` error. If there was an ``'If-Modified-Since'``
header in the request, and the file was not modified after this time,
a ``304``, ``'Not Modified'`` response is sent. Otherwise, the content
type is guessed by calling the :meth:`guess_type` method, which in turn
diff --git a/Doc/library/importlib.resources.abc.rst b/Doc/library/importlib.resources.abc.rst
index 5ea8044e1ec6ca..54995ddbfbca12 100644
--- a/Doc/library/importlib.resources.abc.rst
+++ b/Doc/library/importlib.resources.abc.rst
@@ -22,7 +22,7 @@
something like a data file that lives next to the ``__init__.py``
file of the package. The purpose of this class is to help abstract
out the accessing of such data files so that it does not matter if
- the package and its data file(s) are stored in a e.g. zip file
+ the package and its data file(s) are stored e.g. in a zip file
versus on the file system.
For any of methods of this class, a *resource* argument is
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index d92bb2f8e5cf83..b100e6c8e85e99 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -657,7 +657,7 @@ ABC hierarchy::
something like a data file that lives next to the ``__init__.py``
file of the package. The purpose of this class is to help abstract
out the accessing of such data files so that it does not matter if
- the package and its data file(s) are stored in a e.g. zip file
+ the package and its data file(s) are stored e.g. in a zip file
versus on the file system.
For any of methods of this class, a *resource* argument is
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 7d1aab8e2999c7..f695637e163909 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -42,220 +42,233 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
.. this function name is too big to fit in the ascii-art table below
.. |coroutine-origin-link| replace:: :func:`sys.set_coroutine_origin_tracking_depth`
-+-----------+-------------------+---------------------------+
-| Type | Attribute | Description |
-+===========+===================+===========================+
-| class | __doc__ | documentation string |
-+-----------+-------------------+---------------------------+
-| | __name__ | name with which this |
-| | | class was defined |
-+-----------+-------------------+---------------------------+
-| | __qualname__ | qualified name |
-+-----------+-------------------+---------------------------+
-| | __module__ | name of module in which |
-| | | this class was defined |
-+-----------+-------------------+---------------------------+
-| | __type_params__ | A tuple containing the |
-| | | :ref:`type parameters |
-| | | ` of |
-| | | a generic class |
-+-----------+-------------------+---------------------------+
-| method | __doc__ | documentation string |
-+-----------+-------------------+---------------------------+
-| | __name__ | name with which this |
-| | | method was defined |
-+-----------+-------------------+---------------------------+
-| | __qualname__ | qualified name |
-+-----------+-------------------+---------------------------+
-| | __func__ | function object |
-| | | containing implementation |
-| | | of method |
-+-----------+-------------------+---------------------------+
-| | __self__ | instance to which this |
-| | | method is bound, or |
-| | | ``None`` |
-+-----------+-------------------+---------------------------+
-| | __module__ | name of module in which |
-| | | this method was defined |
-+-----------+-------------------+---------------------------+
-| function | __doc__ | documentation string |
-+-----------+-------------------+---------------------------+
-| | __name__ | name with which this |
-| | | function was defined |
-+-----------+-------------------+---------------------------+
-| | __qualname__ | qualified name |
-+-----------+-------------------+---------------------------+
-| | __code__ | code object containing |
-| | | compiled function |
-| | | :term:`bytecode` |
-+-----------+-------------------+---------------------------+
-| | __defaults__ | tuple of any default |
-| | | values for positional or |
-| | | keyword parameters |
-+-----------+-------------------+---------------------------+
-| | __kwdefaults__ | mapping of any default |
-| | | values for keyword-only |
-| | | parameters |
-+-----------+-------------------+---------------------------+
-| | __globals__ | global namespace in which |
-| | | this function was defined |
-+-----------+-------------------+---------------------------+
-| | __builtins__ | builtins namespace |
-+-----------+-------------------+---------------------------+
-| | __annotations__ | mapping of parameters |
-| | | names to annotations; |
-| | | ``"return"`` key is |
-| | | reserved for return |
-| | | annotations. |
-+-----------+-------------------+---------------------------+
-| | __type_params__ | A tuple containing the |
-| | | :ref:`type parameters |
-| | | ` of |
-| | | a generic function |
-+-----------+-------------------+---------------------------+
-| | __module__ | name of module in which |
-| | | this function was defined |
-+-----------+-------------------+---------------------------+
-| traceback | tb_frame | frame object at this |
-| | | level |
-+-----------+-------------------+---------------------------+
-| | tb_lasti | index of last attempted |
-| | | instruction in bytecode |
-+-----------+-------------------+---------------------------+
-| | tb_lineno | current line number in |
-| | | Python source code |
-+-----------+-------------------+---------------------------+
-| | tb_next | next inner traceback |
-| | | object (called by this |
-| | | level) |
-+-----------+-------------------+---------------------------+
-| frame | f_back | next outer frame object |
-| | | (this frame's caller) |
-+-----------+-------------------+---------------------------+
-| | f_builtins | builtins namespace seen |
-| | | by this frame |
-+-----------+-------------------+---------------------------+
-| | f_code | code object being |
-| | | executed in this frame |
-+-----------+-------------------+---------------------------+
-| | f_globals | global namespace seen by |
-| | | this frame |
-+-----------+-------------------+---------------------------+
-| | f_lasti | index of last attempted |
-| | | instruction in bytecode |
-+-----------+-------------------+---------------------------+
-| | f_lineno | current line number in |
-| | | Python source code |
-+-----------+-------------------+---------------------------+
-| | f_locals | local namespace seen by |
-| | | this frame |
-+-----------+-------------------+---------------------------+
-| | f_trace | tracing function for this |
-| | | frame, or ``None`` |
-+-----------+-------------------+---------------------------+
-| code | co_argcount | number of arguments (not |
-| | | including keyword only |
-| | | arguments, \* or \*\* |
-| | | args) |
-+-----------+-------------------+---------------------------+
-| | co_code | string of raw compiled |
-| | | bytecode |
-+-----------+-------------------+---------------------------+
-| | co_cellvars | tuple of names of cell |
-| | | variables (referenced by |
-| | | containing scopes) |
-+-----------+-------------------+---------------------------+
-| | co_consts | tuple of constants used |
-| | | in the bytecode |
-+-----------+-------------------+---------------------------+
-| | co_filename | name of file in which |
-| | | this code object was |
-| | | created |
-+-----------+-------------------+---------------------------+
-| | co_firstlineno | number of first line in |
-| | | Python source code |
-+-----------+-------------------+---------------------------+
-| | co_flags | bitmap of ``CO_*`` flags, |
-| | | read more :ref:`here |
-| | | `|
-+-----------+-------------------+---------------------------+
-| | co_lnotab | encoded mapping of line |
-| | | numbers to bytecode |
-| | | indices |
-+-----------+-------------------+---------------------------+
-| | co_freevars | tuple of names of free |
-| | | variables (referenced via |
-| | | a function's closure) |
-+-----------+-------------------+---------------------------+
-| | co_posonlyargcount| number of positional only |
-| | | arguments |
-+-----------+-------------------+---------------------------+
-| | co_kwonlyargcount | number of keyword only |
-| | | arguments (not including |
-| | | \*\* arg) |
-+-----------+-------------------+---------------------------+
-| | co_name | name with which this code |
-| | | object was defined |
-+-----------+-------------------+---------------------------+
-| | co_qualname | fully qualified name with |
-| | | which this code object |
-| | | was defined |
-+-----------+-------------------+---------------------------+
-| | co_names | tuple of names other |
-| | | than arguments and |
-| | | function locals |
-+-----------+-------------------+---------------------------+
-| | co_nlocals | number of local variables |
-+-----------+-------------------+---------------------------+
-| | co_stacksize | virtual machine stack |
-| | | space required |
-+-----------+-------------------+---------------------------+
-| | co_varnames | tuple of names of |
-| | | arguments and local |
-| | | variables |
-+-----------+-------------------+---------------------------+
-| generator | __name__ | name |
-+-----------+-------------------+---------------------------+
-| | __qualname__ | qualified name |
-+-----------+-------------------+---------------------------+
-| | gi_frame | frame |
-+-----------+-------------------+---------------------------+
-| | gi_running | is the generator running? |
-+-----------+-------------------+---------------------------+
-| | gi_code | code |
-+-----------+-------------------+---------------------------+
-| | gi_yieldfrom | object being iterated by |
-| | | ``yield from``, or |
-| | | ``None`` |
-+-----------+-------------------+---------------------------+
-| coroutine | __name__ | name |
-+-----------+-------------------+---------------------------+
-| | __qualname__ | qualified name |
-+-----------+-------------------+---------------------------+
-| | cr_await | object being awaited on, |
-| | | or ``None`` |
-+-----------+-------------------+---------------------------+
-| | cr_frame | frame |
-+-----------+-------------------+---------------------------+
-| | cr_running | is the coroutine running? |
-+-----------+-------------------+---------------------------+
-| | cr_code | code |
-+-----------+-------------------+---------------------------+
-| | cr_origin | where coroutine was |
-| | | created, or ``None``. See |
-| | | |coroutine-origin-link| |
-+-----------+-------------------+---------------------------+
-| builtin | __doc__ | documentation string |
-+-----------+-------------------+---------------------------+
-| | __name__ | original name of this |
-| | | function or method |
-+-----------+-------------------+---------------------------+
-| | __qualname__ | qualified name |
-+-----------+-------------------+---------------------------+
-| | __self__ | instance to which a |
-| | | method is bound, or |
-| | | ``None`` |
-+-----------+-------------------+---------------------------+
++-----------------+-------------------+---------------------------+
+| Type | Attribute | Description |
++=================+===================+===========================+
+| class | __doc__ | documentation string |
++-----------------+-------------------+---------------------------+
+| | __name__ | name with which this |
+| | | class was defined |
++-----------------+-------------------+---------------------------+
+| | __qualname__ | qualified name |
++-----------------+-------------------+---------------------------+
+| | __module__ | name of module in which |
+| | | this class was defined |
++-----------------+-------------------+---------------------------+
+| | __type_params__ | A tuple containing the |
+| | | :ref:`type parameters |
+| | | ` of |
+| | | a generic class |
++-----------------+-------------------+---------------------------+
+| method | __doc__ | documentation string |
++-----------------+-------------------+---------------------------+
+| | __name__ | name with which this |
+| | | method was defined |
++-----------------+-------------------+---------------------------+
+| | __qualname__ | qualified name |
++-----------------+-------------------+---------------------------+
+| | __func__ | function object |
+| | | containing implementation |
+| | | of method |
++-----------------+-------------------+---------------------------+
+| | __self__ | instance to which this |
+| | | method is bound, or |
+| | | ``None`` |
++-----------------+-------------------+---------------------------+
+| | __module__ | name of module in which |
+| | | this method was defined |
++-----------------+-------------------+---------------------------+
+| function | __doc__ | documentation string |
++-----------------+-------------------+---------------------------+
+| | __name__ | name with which this |
+| | | function was defined |
++-----------------+-------------------+---------------------------+
+| | __qualname__ | qualified name |
++-----------------+-------------------+---------------------------+
+| | __code__ | code object containing |
+| | | compiled function |
+| | | :term:`bytecode` |
++-----------------+-------------------+---------------------------+
+| | __defaults__ | tuple of any default |
+| | | values for positional or |
+| | | keyword parameters |
++-----------------+-------------------+---------------------------+
+| | __kwdefaults__ | mapping of any default |
+| | | values for keyword-only |
+| | | parameters |
++-----------------+-------------------+---------------------------+
+| | __globals__ | global namespace in which |
+| | | this function was defined |
++-----------------+-------------------+---------------------------+
+| | __builtins__ | builtins namespace |
++-----------------+-------------------+---------------------------+
+| | __annotations__ | mapping of parameters |
+| | | names to annotations; |
+| | | ``"return"`` key is |
+| | | reserved for return |
+| | | annotations. |
++-----------------+-------------------+---------------------------+
+| | __type_params__ | A tuple containing the |
+| | | :ref:`type parameters |
+| | | ` of |
+| | | a generic function |
++-----------------+-------------------+---------------------------+
+| | __module__ | name of module in which |
+| | | this function was defined |
++-----------------+-------------------+---------------------------+
+| traceback | tb_frame | frame object at this |
+| | | level |
++-----------------+-------------------+---------------------------+
+| | tb_lasti | index of last attempted |
+| | | instruction in bytecode |
++-----------------+-------------------+---------------------------+
+| | tb_lineno | current line number in |
+| | | Python source code |
++-----------------+-------------------+---------------------------+
+| | tb_next | next inner traceback |
+| | | object (called by this |
+| | | level) |
++-----------------+-------------------+---------------------------+
+| frame | f_back | next outer frame object |
+| | | (this frame's caller) |
++-----------------+-------------------+---------------------------+
+| | f_builtins | builtins namespace seen |
+| | | by this frame |
++-----------------+-------------------+---------------------------+
+| | f_code | code object being |
+| | | executed in this frame |
++-----------------+-------------------+---------------------------+
+| | f_globals | global namespace seen by |
+| | | this frame |
++-----------------+-------------------+---------------------------+
+| | f_lasti | index of last attempted |
+| | | instruction in bytecode |
++-----------------+-------------------+---------------------------+
+| | f_lineno | current line number in |
+| | | Python source code |
++-----------------+-------------------+---------------------------+
+| | f_locals | local namespace seen by |
+| | | this frame |
++-----------------+-------------------+---------------------------+
+| | f_trace | tracing function for this |
+| | | frame, or ``None`` |
++-----------------+-------------------+---------------------------+
+| code | co_argcount | number of arguments (not |
+| | | including keyword only |
+| | | arguments, \* or \*\* |
+| | | args) |
++-----------------+-------------------+---------------------------+
+| | co_code | string of raw compiled |
+| | | bytecode |
++-----------------+-------------------+---------------------------+
+| | co_cellvars | tuple of names of cell |
+| | | variables (referenced by |
+| | | containing scopes) |
++-----------------+-------------------+---------------------------+
+| | co_consts | tuple of constants used |
+| | | in the bytecode |
++-----------------+-------------------+---------------------------+
+| | co_filename | name of file in which |
+| | | this code object was |
+| | | created |
++-----------------+-------------------+---------------------------+
+| | co_firstlineno | number of first line in |
+| | | Python source code |
++-----------------+-------------------+---------------------------+
+| | co_flags | bitmap of ``CO_*`` flags, |
+| | | read more :ref:`here |
+| | | `|
++-----------------+-------------------+---------------------------+
+| | co_lnotab | encoded mapping of line |
+| | | numbers to bytecode |
+| | | indices |
++-----------------+-------------------+---------------------------+
+| | co_freevars | tuple of names of free |
+| | | variables (referenced via |
+| | | a function's closure) |
++-----------------+-------------------+---------------------------+
+| | co_posonlyargcount| number of positional only |
+| | | arguments |
++-----------------+-------------------+---------------------------+
+| | co_kwonlyargcount | number of keyword only |
+| | | arguments (not including |
+| | | \*\* arg) |
++-----------------+-------------------+---------------------------+
+| | co_name | name with which this code |
+| | | object was defined |
++-----------------+-------------------+---------------------------+
+| | co_qualname | fully qualified name with |
+| | | which this code object |
+| | | was defined |
++-----------------+-------------------+---------------------------+
+| | co_names | tuple of names other |
+| | | than arguments and |
+| | | function locals |
++-----------------+-------------------+---------------------------+
+| | co_nlocals | number of local variables |
++-----------------+-------------------+---------------------------+
+| | co_stacksize | virtual machine stack |
+| | | space required |
++-----------------+-------------------+---------------------------+
+| | co_varnames | tuple of names of |
+| | | arguments and local |
+| | | variables |
++-----------------+-------------------+---------------------------+
+| generator | __name__ | name |
++-----------------+-------------------+---------------------------+
+| | __qualname__ | qualified name |
++-----------------+-------------------+---------------------------+
+| | gi_frame | frame |
++-----------------+-------------------+---------------------------+
+| | gi_running | is the generator running? |
++-----------------+-------------------+---------------------------+
+| | gi_code | code |
++-----------------+-------------------+---------------------------+
+| | gi_yieldfrom | object being iterated by |
+| | | ``yield from``, or |
+| | | ``None`` |
++-----------------+-------------------+---------------------------+
+| async generator | __name__ | name |
++-----------------+-------------------+---------------------------+
+| | __qualname__ | qualified name |
++-----------------+-------------------+---------------------------+
+| | ag_await | object being awaited on, |
+| | | or ``None`` |
++-----------------+-------------------+---------------------------+
+| | ag_frame | frame |
++-----------------+-------------------+---------------------------+
+| | ag_running | is the generator running? |
++-----------------+-------------------+---------------------------+
+| | ag_code | code |
++-----------------+-------------------+---------------------------+
+| coroutine | __name__ | name |
++-----------------+-------------------+---------------------------+
+| | __qualname__ | qualified name |
++-----------------+-------------------+---------------------------+
+| | cr_await | object being awaited on, |
+| | | or ``None`` |
++-----------------+-------------------+---------------------------+
+| | cr_frame | frame |
++-----------------+-------------------+---------------------------+
+| | cr_running | is the coroutine running? |
++-----------------+-------------------+---------------------------+
+| | cr_code | code |
++-----------------+-------------------+---------------------------+
+| | cr_origin | where coroutine was |
+| | | created, or ``None``. See |
+| | | |coroutine-origin-link| |
++-----------------+-------------------+---------------------------+
+| builtin | __doc__ | documentation string |
++-----------------+-------------------+---------------------------+
+| | __name__ | original name of this |
+| | | function or method |
++-----------------+-------------------+---------------------------+
+| | __qualname__ | qualified name |
++-----------------+-------------------+---------------------------+
+| | __self__ | instance to which a |
+| | | method is bound, or |
+| | | ``None`` |
++-----------------+-------------------+---------------------------+
.. versionchanged:: 3.5
@@ -437,7 +450,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
.. versionchanged:: 3.8
Functions wrapped in :func:`functools.partial` now return ``True`` if the
- wrapped function is a :term:`asynchronous generator` function.
+ wrapped function is an :term:`asynchronous generator` function.
.. function:: isasyncgen(object)
@@ -896,7 +909,7 @@ function.
.. attribute:: Parameter.kind.description
- Describes a enum value of :attr:`Parameter.kind`.
+ Describes an enum value of :attr:`Parameter.kind`.
.. versionadded:: 3.8
diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst
index d359451b397807..74ad25464d88c5 100644
--- a/Doc/library/ipaddress.rst
+++ b/Doc/library/ipaddress.rst
@@ -983,7 +983,7 @@ The module also provides the following module level functions:
.. function:: collapse_addresses(addresses)
Return an iterator of the collapsed :class:`IPv4Network` or
- :class:`IPv6Network` objects. *addresses* is an iterator of
+ :class:`IPv6Network` objects. *addresses* is an :term:`iterable` of
:class:`IPv4Network` or :class:`IPv6Network` objects. A :exc:`TypeError` is
raised if *addresses* contains mixed version objects.
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index 21bb3f1f840336..3fab46c3c0a5b4 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -329,7 +329,7 @@ loops that truncate the stream.
yield n
n += step
- When counting with floating point numbers, better accuracy can sometimes be
+ When counting with floating-point numbers, better accuracy can sometimes be
achieved by substituting multiplicative code such as: ``(start + step * i
for i in count())``.
diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst
index 10c376397cf20a..60975bf9177dad 100644
--- a/Doc/library/locale.rst
+++ b/Doc/library/locale.rst
@@ -434,7 +434,7 @@ The :mod:`locale` module defines the following exception and functions:
.. function:: format_string(format, val, grouping=False, monetary=False)
Formats a number *val* according to the current :const:`LC_NUMERIC` setting.
- The format follows the conventions of the ``%`` operator. For floating point
+ The format follows the conventions of the ``%`` operator. For floating-point
values, the decimal point is modified if appropriate. If *grouping* is ``True``,
also takes the grouping into account.
@@ -465,7 +465,7 @@ The :mod:`locale` module defines the following exception and functions:
.. function:: str(float)
- Formats a floating point number using the same format as the built-in function
+ Formats a floating-point number using the same format as the built-in function
``str(float)``, but takes the decimal point into account.
diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst
index 23aac191f0576c..2722384d174bef 100644
--- a/Doc/library/logging.config.rst
+++ b/Doc/library/logging.config.rst
@@ -752,9 +752,12 @@ The ``queue`` and ``listener`` keys are optional.
If the ``queue`` key is present, the corresponding value can be one of the following:
-* An actual instance of :class:`queue.Queue` or a subclass thereof. This is of course
- only possible if you are constructing or modifying the configuration dictionary in
- code.
+* An object implementing the :class:`queue.Queue` public API. For instance,
+ this may be an actual instance of :class:`queue.Queue` or a subclass thereof,
+ or a proxy obtained by :meth:`multiprocessing.managers.SyncManager.Queue`.
+
+ This is of course only possible if you are constructing or modifying
+ the configuration dictionary in code.
* A string that resolves to a callable which, when called with no arguments, returns
the :class:`queue.Queue` instance to use. That callable could be a
diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst
index 1e4e728395babc..6eb8dec44eb34a 100644
--- a/Doc/library/mailbox.rst
+++ b/Doc/library/mailbox.rst
@@ -1278,7 +1278,7 @@ When an :class:`!MHMessage` instance is created based upon a
.. method:: get_visible()
- Return an :class:`Message` instance whose headers are the message's
+ Return a :class:`Message` instance whose headers are the message's
visible headers and whose body is empty.
diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst
index ce549b73fe5b46..a85d92068109b9 100644
--- a/Doc/library/marshal.rst
+++ b/Doc/library/marshal.rst
@@ -38,8 +38,8 @@ supports a substantially wider range of objects than marshal.
Not all Python object types are supported; in general, only objects whose value
is independent from a particular invocation of Python can be written and read by
-this module. The following types are supported: booleans, integers, floating
-point numbers, complex numbers, strings, bytes, bytearrays, tuples, lists, sets,
+this module. The following types are supported: booleans, integers, floating-point
+numbers, complex numbers, strings, bytes, bytearrays, tuples, lists, sets,
frozensets, dictionaries, and code objects, where it should be understood that
tuples, lists, sets, frozensets and dictionaries are only supported as long as
the values contained therein are themselves supported. The
@@ -121,7 +121,7 @@ In addition, the following constants are defined:
Indicates the format that the module uses. Version 0 is the historical
format, version 1 shares interned strings and version 2 uses a binary format
- for floating point numbers.
+ for floating-point numbers.
Version 3 adds support for object instancing and recursion.
The current version is 4.
diff --git a/Doc/library/math.rst b/Doc/library/math.rst
index b6a7d98a29534d..40742fdafeac03 100644
--- a/Doc/library/math.rst
+++ b/Doc/library/math.rst
@@ -107,7 +107,7 @@ Number-theoretic and representation functions
.. function:: fsum(iterable)
- Return an accurate floating point sum of values in the iterable. Avoids
+ Return an accurate floating-point sum of values in the iterable. Avoids
loss of precision by tracking multiple intermediate partial sums.
The algorithm's accuracy depends on IEEE-754 arithmetic guarantees and the
@@ -117,7 +117,7 @@ Number-theoretic and representation functions
least significant bit.
For further discussion and two alternative approaches, see the `ASPN cookbook
- recipes for accurate floating point summation
+ recipes for accurate floating-point summation
`_\.
@@ -288,7 +288,7 @@ Number-theoretic and representation functions
If the result of the remainder operation is zero, that zero will have
the same sign as *x*.
- On platforms using IEEE 754 binary floating-point, the result of this
+ On platforms using IEEE 754 binary floating point, the result of this
operation is always exactly representable: no rounding error is introduced.
.. versionadded:: 3.7
diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst
index 930b4793189a6f..1522285b4efe40 100644
--- a/Doc/library/mimetypes.rst
+++ b/Doc/library/mimetypes.rst
@@ -272,3 +272,13 @@ than one MIME-type database; it provides an interface similar to the one of the
types, else to the list of non-standard types.
.. versionadded:: 3.2
+
+
+ .. method:: MimeTypes.add_type(type, ext, strict=True)
+
+ Add a mapping from the MIME type *type* to the extension *ext*. When the
+ extension is already known, the new type will replace the old one. When the type
+ is already known the extension will be added to the list of known extensions.
+
+ When *strict* is ``True`` (the default), the mapping will be added to the
+ official MIME types, otherwise to the non-standard ones.
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index d6474ef975b506..a74f582b5f0465 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -254,6 +254,7 @@ processes:
p.join()
Queues are thread and process safe.
+ Any object put into a :mod:`~multiprocessing` queue will be serialized.
**Pipes**
@@ -281,6 +282,8 @@ processes:
of corruption from processes using different ends of the pipe at the same
time.
+ The :meth:`~Connection.send` method serializes the the object and
+ :meth:`~Connection.recv` re-creates the object.
Synchronization between processes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -745,6 +748,11 @@ If you use :class:`JoinableQueue` then you **must** call
semaphore used to count the number of unfinished tasks may eventually overflow,
raising an exception.
+One difference from other Python queue implementations, is that :mod:`multiprocessing`
+queues serializes all objects that are put into them using :mod:`pickle`.
+The object return by the get method is a re-created object that does not share memory
+with the original object.
+
Note that one can also create a shared queue by using a manager object -- see
:ref:`multiprocessing-managers`.
@@ -811,6 +819,8 @@ For an example of the usage of queues for interprocess communication see
used for receiving messages and ``conn2`` can only be used for sending
messages.
+ The :meth:`~multiprocessing.Connection.send` method serializes the the object using
+ :mod:`pickle` and the :meth:`~multiprocessing.Connection.recv` re-creates the object.
.. class:: Queue([maxsize])
@@ -837,6 +847,8 @@ For an example of the usage of queues for interprocess communication see
Return ``True`` if the queue is empty, ``False`` otherwise. Because of
multithreading/multiprocessing semantics, this is not reliable.
+ May raise an :exc:`OSError` on closed queues. (not guaranteed)
+
.. method:: full()
Return ``True`` if the queue is full, ``False`` otherwise. Because of
@@ -940,6 +952,8 @@ For an example of the usage of queues for interprocess communication see
Return ``True`` if the queue is empty, ``False`` otherwise.
+ Always raises an :exc:`OSError` if the SimpleQueue is closed.
+
.. method:: get()
Remove and return an item from the queue.
@@ -1452,17 +1466,6 @@ object -- see :ref:`multiprocessing-managers`.
On macOS, ``sem_timedwait`` is unsupported, so calling ``acquire()`` with
a timeout will emulate that function's behavior using a sleeping loop.
-.. note::
-
- If the SIGINT signal generated by :kbd:`Ctrl-C` arrives while the main thread is
- blocked by a call to :meth:`BoundedSemaphore.acquire`, :meth:`Lock.acquire`,
- :meth:`RLock.acquire`, :meth:`Semaphore.acquire`, :meth:`Condition.acquire`
- or :meth:`Condition.wait` then the call will be immediately interrupted and
- :exc:`KeyboardInterrupt` will be raised.
-
- This differs from the behaviour of :mod:`threading` where SIGINT will be
- ignored while the equivalent blocking calls are in progress.
-
.. note::
Some of this package's functionality requires a functioning shared semaphore
diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst
index fc652d23f4f880..15b5d5c3466d32 100644
--- a/Doc/library/optparse.rst
+++ b/Doc/library/optparse.rst
@@ -1351,7 +1351,7 @@ The whole point of creating and populating an OptionParser is to call its
the list of arguments to process (default: ``sys.argv[1:]``)
``values``
- an :class:`Values` object to store option arguments in (default: a
+ a :class:`Values` object to store option arguments in (default: a
new instance of :class:`Values`) -- if you give an existing object, the
option defaults will not be initialized on it
diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst
index c5004c3f0dfe2b..51e89087e7fa54 100644
--- a/Doc/library/os.path.rst
+++ b/Doc/library/os.path.rst
@@ -81,7 +81,7 @@ the :mod:`glob` module.)
Return the longest common sub-path of each pathname in the sequence
*paths*. Raise :exc:`ValueError` if *paths* contain both absolute
- and relative pathnames, the *paths* are on the different drives or
+ and relative pathnames, if *paths* are on different drives, or
if *paths* is empty. Unlike :func:`commonprefix`, this returns a
valid path.
@@ -198,14 +198,14 @@ the :mod:`glob` module.)
.. function:: getatime(path)
- Return the time of last access of *path*. The return value is a floating point number giving
+ Return the time of last access of *path*. The return value is a floating-point number giving
the number of seconds since the epoch (see the :mod:`time` module). Raise
:exc:`OSError` if the file does not exist or is inaccessible.
.. function:: getmtime(path)
- Return the time of last modification of *path*. The return value is a floating point number
+ Return the time of last modification of *path*. The return value is a floating-point number
giving the number of seconds since the epoch (see the :mod:`time` module).
Raise :exc:`OSError` if the file does not exist or is inaccessible.
@@ -359,7 +359,7 @@ the :mod:`glob` module.)
that contains symbolic links. On Windows, it converts forward slashes to
backward slashes. To normalize case, use :func:`normcase`.
- .. note::
+ .. note::
On POSIX systems, in accordance with `IEEE Std 1003.1 2013 Edition; 4.13
Pathname Resolution `_,
if a pathname begins with exactly two slashes, the first component
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index a793d244de9a04..e9ca3be73af0f9 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -1497,7 +1497,7 @@ or `the MSDN `_ on Windo
.. function:: pwritev(fd, buffers, offset, flags=0, /)
- Write the *buffers* contents to file descriptor *fd* at a offset *offset*,
+ Write the *buffers* contents to file descriptor *fd* at an offset *offset*,
leaving the file offset unchanged. *buffers* must be a sequence of
:term:`bytes-like objects `. Buffers are processed in
array order. Entire contents of the first buffer is written before
@@ -3701,7 +3701,7 @@ features:
new file descriptor is :ref:`non-inheritable `.
*initval* is the initial value of the event counter. The initial value
- must be an 32 bit unsigned integer. Please note that the initial value is
+ must be a 32 bit unsigned integer. Please note that the initial value is
limited to a 32 bit unsigned int although the event counter is an unsigned
64 bit integer with a maximum value of 2\ :sup:`64`\ -\ 2.
@@ -3780,7 +3780,7 @@ features:
.. data:: EFD_SEMAPHORE
- Provide semaphore-like semantics for reads from a :func:`eventfd` file
+ Provide semaphore-like semantics for reads from an :func:`eventfd` file
descriptor. On read the internal counter is decremented by one.
.. availability:: Linux >= 2.6.30
diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst
index d4b0e0720849a4..c5be7dc25b3271 100644
--- a/Doc/library/pathlib.rst
+++ b/Doc/library/pathlib.rst
@@ -21,6 +21,12 @@ inherit from pure paths but also provide I/O operations.
.. image:: pathlib-inheritance.png
:align: center
:class: invert-in-dark-mode
+ :alt: Inheritance diagram showing the classes available in pathlib. The
+ most basic class is PurePath, which has three direct subclasses:
+ PurePosixPath, PureWindowsPath, and Path. Further to these four
+ classes, there are two classes that use multiple inheritance:
+ PosixPath subclasses PurePosixPath and Path, and WindowsPath
+ subclasses PureWindowsPath and Path.
If you've never used this module before or just aren't sure which class is
right for your task, :class:`Path` is most likely what you need. It instantiates
@@ -789,6 +795,102 @@ bugs or failures in your application)::
% (cls.__name__,))
NotImplementedError: cannot instantiate 'WindowsPath' on your system
+Some concrete path methods can raise an :exc:`OSError` if a system call fails
+(for example because the path doesn't exist).
+
+
+Expanding and resolving paths
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. classmethod:: Path.home()
+
+ Return a new path object representing the user's home directory (as
+ returned by :func:`os.path.expanduser` with ``~`` construct). If the home
+ directory can't be resolved, :exc:`RuntimeError` is raised.
+
+ ::
+
+ >>> Path.home()
+ PosixPath('/home/antoine')
+
+ .. versionadded:: 3.5
+
+
+.. method:: Path.expanduser()
+
+ Return a new path with expanded ``~`` and ``~user`` constructs,
+ as returned by :meth:`os.path.expanduser`. If a home directory can't be
+ resolved, :exc:`RuntimeError` is raised.
+
+ ::
+
+ >>> p = PosixPath('~/films/Monty Python')
+ >>> p.expanduser()
+ PosixPath('/home/eric/films/Monty Python')
+
+ .. versionadded:: 3.5
+
+
+.. classmethod:: Path.cwd()
+
+ Return a new path object representing the current directory (as returned
+ by :func:`os.getcwd`)::
+
+ >>> Path.cwd()
+ PosixPath('/home/antoine/pathlib')
+
+
+.. method:: Path.absolute()
+
+ Make the path absolute, without normalization or resolving symlinks.
+ Returns a new path object::
+
+ >>> p = Path('tests')
+ >>> p
+ PosixPath('tests')
+ >>> p.absolute()
+ PosixPath('/home/antoine/pathlib/tests')
+
+
+.. method:: Path.resolve(strict=False)
+
+ Make the path absolute, resolving any symlinks. A new path object is
+ returned::
+
+ >>> p = Path()
+ >>> p
+ PosixPath('.')
+ >>> p.resolve()
+ PosixPath('/home/antoine/pathlib')
+
+ "``..``" components are also eliminated (this is the only method to do so)::
+
+ >>> p = Path('docs/../setup.py')
+ >>> p.resolve()
+ PosixPath('/home/antoine/pathlib/setup.py')
+
+ If the path doesn't exist and *strict* is ``True``, :exc:`FileNotFoundError`
+ is raised. If *strict* is ``False``, the path is resolved as far as possible
+ and any remainder is appended without checking whether it exists. If an
+ infinite loop is encountered along the resolution path, :exc:`RuntimeError`
+ is raised.
+
+ .. versionchanged:: 3.6
+ The *strict* parameter was added (pre-3.6 behavior is strict).
+
+
+.. method:: Path.readlink()
+
+ Return the path to which the symbolic link points (as returned by
+ :func:`os.readlink`)::
+
+ >>> p = Path('mylink')
+ >>> p.symlink_to('setup.py')
+ >>> p.readlink()
+ PosixPath('setup.py')
+
+ .. versionadded:: 3.9
+
Querying file type and status
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -805,7 +907,7 @@ Querying file type and status
.. method:: Path.stat(*, follow_symlinks=True)
- Return a :class:`os.stat_result` object containing information about this path, like :func:`os.stat`.
+ Return an :class:`os.stat_result` object containing information about this path, like :func:`os.stat`.
The result is looked up at each call to this method.
This method normally follows symlinks; to stat a symlink add the argument
@@ -1040,71 +1142,32 @@ Reading and writing files
.. versionadded:: 3.5
-Other methods
-^^^^^^^^^^^^^
+Reading directories
+^^^^^^^^^^^^^^^^^^^
-Many of these methods can raise an :exc:`OSError` if a system call fails (for
-example because the path doesn't exist).
-
-
-.. classmethod:: Path.cwd()
-
- Return a new path object representing the current directory (as returned
- by :func:`os.getcwd`)::
-
- >>> Path.cwd()
- PosixPath('/home/antoine/pathlib')
-
-
-.. classmethod:: Path.home()
-
- Return a new path object representing the user's home directory (as
- returned by :func:`os.path.expanduser` with ``~`` construct). If the home
- directory can't be resolved, :exc:`RuntimeError` is raised.
-
- ::
-
- >>> Path.home()
- PosixPath('/home/antoine')
-
- .. versionadded:: 3.5
-
-
-.. method:: Path.chmod(mode, *, follow_symlinks=True)
-
- Change the file mode and permissions, like :func:`os.chmod`.
-
- This method normally follows symlinks. Some Unix flavours support changing
- permissions on the symlink itself; on these platforms you may add the
- argument ``follow_symlinks=False``, or use :meth:`~Path.lchmod`.
-
- ::
-
- >>> p = Path('setup.py')
- >>> p.stat().st_mode
- 33277
- >>> p.chmod(0o444)
- >>> p.stat().st_mode
- 33060
-
- .. versionchanged:: 3.10
- The *follow_symlinks* parameter was added.
-
-
-.. method:: Path.expanduser()
-
- Return a new path with expanded ``~`` and ``~user`` constructs,
- as returned by :meth:`os.path.expanduser`. If a home directory can't be
- resolved, :exc:`RuntimeError` is raised.
+.. method:: Path.iterdir()
- ::
+ When the path points to a directory, yield path objects of the directory
+ contents::
- >>> p = PosixPath('~/films/Monty Python')
- >>> p.expanduser()
- PosixPath('/home/eric/films/Monty Python')
+ >>> p = Path('docs')
+ >>> for child in p.iterdir(): child
+ ...
+ PosixPath('docs/conf.py')
+ PosixPath('docs/_templates')
+ PosixPath('docs/make.bat')
+ PosixPath('docs/index.rst')
+ PosixPath('docs/_build')
+ PosixPath('docs/_static')
+ PosixPath('docs/Makefile')
- .. versionadded:: 3.5
+ The children are yielded in arbitrary order, and the special entries
+ ``'.'`` and ``'..'`` are not included. If a file is removed from or added
+ to the directory after creating the iterator, it is unspecified whether
+ a path object for that file is included.
+ If the path is not a directory or otherwise inaccessible, :exc:`OSError` is
+ raised.
.. method:: Path.glob(pattern, *, case_sensitive=None)
@@ -1150,32 +1213,33 @@ example because the path doesn't exist).
The *case_sensitive* parameter was added.
-.. method:: Path.group()
+.. method:: Path.rglob(pattern, *, case_sensitive=None)
- Return the name of the group owning the file. :exc:`KeyError` is raised
- if the file's gid isn't found in the system database.
+ Glob the given relative *pattern* recursively. This is like calling
+ :func:`Path.glob` with "``**/``" added in front of the *pattern*, where
+ *patterns* are the same as for :mod:`fnmatch`::
+ >>> sorted(Path().rglob("*.py"))
+ [PosixPath('build/lib/pathlib.py'),
+ PosixPath('docs/conf.py'),
+ PosixPath('pathlib.py'),
+ PosixPath('setup.py'),
+ PosixPath('test_pathlib.py')]
-.. method:: Path.iterdir()
+ By default, or when the *case_sensitive* keyword-only argument is set to
+ ``None``, this method matches paths using platform-specific casing rules:
+ typically, case-sensitive on POSIX, and case-insensitive on Windows.
+ Set *case_sensitive* to ``True`` or ``False`` to override this behaviour.
- When the path points to a directory, yield path objects of the directory
- contents::
+ .. audit-event:: pathlib.Path.rglob self,pattern pathlib.Path.rglob
- >>> p = Path('docs')
- >>> for child in p.iterdir(): child
- ...
- PosixPath('docs/conf.py')
- PosixPath('docs/_templates')
- PosixPath('docs/make.bat')
- PosixPath('docs/index.rst')
- PosixPath('docs/_build')
- PosixPath('docs/_static')
- PosixPath('docs/Makefile')
+ .. versionchanged:: 3.11
+ Return only directories if *pattern* ends with a pathname components
+ separator (:data:`~os.sep` or :data:`~os.altsep`).
+
+ .. versionchanged:: 3.12
+ The *case_sensitive* parameter was added.
- The children are yielded in arbitrary order, and the special entries
- ``'.'`` and ``'..'`` are not included. If a file is removed from or added
- to the directory after creating the iterator, whether a path object for
- that file be included is unspecified.
.. method:: Path.walk(top_down=True, on_error=None, follow_symlinks=False)
@@ -1272,16 +1336,27 @@ example because the path doesn't exist).
.. versionadded:: 3.12
-.. method:: Path.lchmod(mode)
- Like :meth:`Path.chmod` but, if the path points to a symbolic link, the
- symbolic link's mode is changed rather than its target's.
+Creating files and directories
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. method:: Path.touch(mode=0o666, exist_ok=True)
+
+ Create a file at this given path. If *mode* is given, it is combined
+ with the process's ``umask`` value to determine the file mode and access
+ flags. If the file already exists, the function succeeds when *exist_ok*
+ is true (and its modification time is updated to the current time),
+ otherwise :exc:`FileExistsError` is raised.
+
+ .. seealso::
+ The :meth:`~Path.open`, :meth:`~Path.write_text` and
+ :meth:`~Path.write_bytes` methods are often used to create files.
.. method:: Path.mkdir(mode=0o777, parents=False, exist_ok=False)
Create a new directory at this given path. If *mode* is given, it is
- combined with the process' ``umask`` value to determine the file mode
+ combined with the process's ``umask`` value to determine the file mode
and access flags. If the path already exists, :exc:`FileExistsError`
is raised.
@@ -1303,30 +1378,51 @@ example because the path doesn't exist).
The *exist_ok* parameter was added.
-.. method:: Path.owner()
-
- Return the name of the user owning the file. :exc:`KeyError` is raised
- if the file's uid isn't found in the system database.
+.. method:: Path.symlink_to(target, target_is_directory=False)
+ Make this path a symbolic link pointing to *target*.
-.. method:: Path.readlink()
+ On Windows, a symlink represents either a file or a directory, and does not
+ morph to the target dynamically. If the target is present, the type of the
+ symlink will be created to match. Otherwise, the symlink will be created
+ as a directory if *target_is_directory* is true or a file symlink (the
+ default) otherwise. On non-Windows platforms, *target_is_directory* is ignored.
- Return the path to which the symbolic link points (as returned by
- :func:`os.readlink`)::
+ ::
>>> p = Path('mylink')
>>> p.symlink_to('setup.py')
- >>> p.readlink()
- PosixPath('setup.py')
+ >>> p.resolve()
+ PosixPath('/home/antoine/pathlib/setup.py')
+ >>> p.stat().st_size
+ 956
+ >>> p.lstat().st_size
+ 8
- .. versionadded:: 3.9
+ .. note::
+ The order of arguments (link, target) is the reverse
+ of :func:`os.symlink`'s.
+
+
+.. method:: Path.hardlink_to(target)
+
+ Make this path a hard link to the same file as *target*.
+
+ .. note::
+ The order of arguments (link, target) is the reverse
+ of :func:`os.link`'s.
+
+ .. versionadded:: 3.10
+Renaming and deleting
+^^^^^^^^^^^^^^^^^^^^^
+
.. method:: Path.rename(target)
- Rename this file or directory to the given *target*, and return a new Path
- instance pointing to *target*. On Unix, if *target* exists and is a file,
- it will be replaced silently if the user has permission.
+ Rename this file or directory to the given *target*, and return a new
+ :class:`!Path` instance pointing to *target*. On Unix, if *target* exists
+ and is a file, it will be replaced silently if the user has permission.
On Windows, if *target* exists, :exc:`FileExistsError` will be raised.
*target* can be either a string or another path object::
@@ -1340,93 +1436,42 @@ example because the path doesn't exist).
'some text'
The target path may be absolute or relative. Relative paths are interpreted
- relative to the current working directory, *not* the directory of the Path
- object.
+ relative to the current working directory, *not* the directory of the
+ :class:`!Path` object.
It is implemented in terms of :func:`os.rename` and gives the same guarantees.
.. versionchanged:: 3.8
- Added return value, return the new Path instance.
+ Added return value, return the new :class:`!Path` instance.
.. method:: Path.replace(target)
- Rename this file or directory to the given *target*, and return a new Path
- instance pointing to *target*. If *target* points to an existing file or
- empty directory, it will be unconditionally replaced.
+ Rename this file or directory to the given *target*, and return a new
+ :class:`!Path` instance pointing to *target*. If *target* points to an
+ existing file or empty directory, it will be unconditionally replaced.
The target path may be absolute or relative. Relative paths are interpreted
- relative to the current working directory, *not* the directory of the Path
- object.
+ relative to the current working directory, *not* the directory of the
+ :class:`!Path` object.
.. versionchanged:: 3.8
- Added return value, return the new Path instance.
-
-
-.. method:: Path.absolute()
-
- Make the path absolute, without normalization or resolving symlinks.
- Returns a new path object::
-
- >>> p = Path('tests')
- >>> p
- PosixPath('tests')
- >>> p.absolute()
- PosixPath('/home/antoine/pathlib/tests')
-
-
-.. method:: Path.resolve(strict=False)
-
- Make the path absolute, resolving any symlinks. A new path object is
- returned::
-
- >>> p = Path()
- >>> p
- PosixPath('.')
- >>> p.resolve()
- PosixPath('/home/antoine/pathlib')
-
- "``..``" components are also eliminated (this is the only method to do so)::
+ Added return value, return the new :class:`!Path` instance.
- >>> p = Path('docs/../setup.py')
- >>> p.resolve()
- PosixPath('/home/antoine/pathlib/setup.py')
-
- If the path doesn't exist and *strict* is ``True``, :exc:`FileNotFoundError`
- is raised. If *strict* is ``False``, the path is resolved as far as possible
- and any remainder is appended without checking whether it exists. If an
- infinite loop is encountered along the resolution path, :exc:`RuntimeError`
- is raised.
-
- .. versionchanged:: 3.6
- The *strict* parameter was added (pre-3.6 behavior is strict).
-.. method:: Path.rglob(pattern, *, case_sensitive=None)
-
- Glob the given relative *pattern* recursively. This is like calling
- :func:`Path.glob` with "``**/``" added in front of the *pattern*, where
- *patterns* are the same as for :mod:`fnmatch`::
-
- >>> sorted(Path().rglob("*.py"))
- [PosixPath('build/lib/pathlib.py'),
- PosixPath('docs/conf.py'),
- PosixPath('pathlib.py'),
- PosixPath('setup.py'),
- PosixPath('test_pathlib.py')]
+.. method:: Path.unlink(missing_ok=False)
- By default, or when the *case_sensitive* keyword-only argument is set to
- ``None``, this method matches paths using platform-specific casing rules:
- typically, case-sensitive on POSIX, and case-insensitive on Windows.
- Set *case_sensitive* to ``True`` or ``False`` to override this behaviour.
+ Remove this file or symbolic link. If the path points to a directory,
+ use :func:`Path.rmdir` instead.
- .. audit-event:: pathlib.Path.rglob self,pattern pathlib.Path.rglob
+ If *missing_ok* is false (the default), :exc:`FileNotFoundError` is
+ raised if the path does not exist.
- .. versionchanged:: 3.11
- Return only directories if *pattern* ends with a pathname components
- separator (:data:`~os.sep` or :data:`~os.altsep`).
+ If *missing_ok* is true, :exc:`FileNotFoundError` exceptions will be
+ ignored (same behavior as the POSIX ``rm -f`` command).
- .. versionchanged:: 3.12
- The *case_sensitive* parameter was added.
+ .. versionchanged:: 3.8
+ The *missing_ok* parameter was added.
.. method:: Path.rmdir()
@@ -1434,64 +1479,46 @@ example because the path doesn't exist).
Remove this directory. The directory must be empty.
-.. method:: Path.symlink_to(target, target_is_directory=False)
-
- Make this path a symbolic link pointing to *target*.
-
- On Windows, a symlink represents either a file or a directory, and does not
- morph to the target dynamically. If the target is present, the type of the
- symlink will be created to match. Otherwise, the symlink will be created
- as a directory if *target_is_directory* is ``True`` or a file symlink (the
- default) otherwise. On non-Windows platforms, *target_is_directory* is ignored.
-
- ::
+Permissions and ownership
+^^^^^^^^^^^^^^^^^^^^^^^^^
- >>> p = Path('mylink')
- >>> p.symlink_to('setup.py')
- >>> p.resolve()
- PosixPath('/home/antoine/pathlib/setup.py')
- >>> p.stat().st_size
- 956
- >>> p.lstat().st_size
- 8
+.. method:: Path.owner()
- .. note::
- The order of arguments (link, target) is the reverse
- of :func:`os.symlink`'s.
+ Return the name of the user owning the file. :exc:`KeyError` is raised
+ if the file's user identifier (UID) isn't found in the system database.
-.. method:: Path.hardlink_to(target)
- Make this path a hard link to the same file as *target*.
+.. method:: Path.group()
- .. note::
- The order of arguments (link, target) is the reverse
- of :func:`os.link`'s.
+ Return the name of the group owning the file. :exc:`KeyError` is raised
+ if the file's group identifier (GID) isn't found in the system database.
- .. versionadded:: 3.10
+.. method:: Path.chmod(mode, *, follow_symlinks=True)
-.. method:: Path.touch(mode=0o666, exist_ok=True)
+ Change the file mode and permissions, like :func:`os.chmod`.
- Create a file at this given path. If *mode* is given, it is combined
- with the process' ``umask`` value to determine the file mode and access
- flags. If the file already exists, the function succeeds if *exist_ok*
- is true (and its modification time is updated to the current time),
- otherwise :exc:`FileExistsError` is raised.
+ This method normally follows symlinks. Some Unix flavours support changing
+ permissions on the symlink itself; on these platforms you may add the
+ argument ``follow_symlinks=False``, or use :meth:`~Path.lchmod`.
+ ::
-.. method:: Path.unlink(missing_ok=False)
+ >>> p = Path('setup.py')
+ >>> p.stat().st_mode
+ 33277
+ >>> p.chmod(0o444)
+ >>> p.stat().st_mode
+ 33060
- Remove this file or symbolic link. If the path points to a directory,
- use :func:`Path.rmdir` instead.
+ .. versionchanged:: 3.10
+ The *follow_symlinks* parameter was added.
- If *missing_ok* is false (the default), :exc:`FileNotFoundError` is
- raised if the path does not exist.
- If *missing_ok* is true, :exc:`FileNotFoundError` exceptions will be
- ignored (same behavior as the POSIX ``rm -f`` command).
+.. method:: Path.lchmod(mode)
- .. versionchanged:: 3.8
- The *missing_ok* parameter was added.
+ Like :meth:`Path.chmod` but, if the path points to a symbolic link, the
+ symbolic link's mode is changed rather than its target's.
Correspondence to tools in the :mod:`os` module
@@ -1500,51 +1527,54 @@ Correspondence to tools in the :mod:`os` module
Below is a table mapping various :mod:`os` functions to their corresponding
:class:`PurePath`/:class:`Path` equivalent.
-.. note::
-
- Not all pairs of functions/methods below are equivalent. Some of them,
- despite having some overlapping use-cases, have different semantics. They
- include :func:`os.path.abspath` and :meth:`Path.absolute`,
- :func:`os.path.relpath` and :meth:`PurePath.relative_to`.
-
-==================================== ==============================
-:mod:`os` and :mod:`os.path` :mod:`pathlib`
-==================================== ==============================
-:func:`os.path.abspath` :meth:`Path.absolute` [#]_
-:func:`os.path.realpath` :meth:`Path.resolve`
-:func:`os.chmod` :meth:`Path.chmod`
-:func:`os.mkdir` :meth:`Path.mkdir`
-:func:`os.makedirs` :meth:`Path.mkdir`
-:func:`os.rename` :meth:`Path.rename`
-:func:`os.replace` :meth:`Path.replace`
-:func:`os.rmdir` :meth:`Path.rmdir`
-:func:`os.remove`, :func:`os.unlink` :meth:`Path.unlink`
-:func:`os.getcwd` :func:`Path.cwd`
-:func:`os.path.exists` :meth:`Path.exists`
-:func:`os.path.expanduser` :meth:`Path.expanduser` and
- :meth:`Path.home`
-:func:`os.listdir` :meth:`Path.iterdir`
-:func:`os.walk` :meth:`Path.walk`
-:func:`os.path.isdir` :meth:`Path.is_dir`
-:func:`os.path.isfile` :meth:`Path.is_file`
-:func:`os.path.islink` :meth:`Path.is_symlink`
-:func:`os.link` :meth:`Path.hardlink_to`
-:func:`os.symlink` :meth:`Path.symlink_to`
-:func:`os.readlink` :meth:`Path.readlink`
-:func:`os.path.relpath` :meth:`PurePath.relative_to` [#]_
-:func:`os.stat` :meth:`Path.stat`,
- :meth:`Path.owner`,
- :meth:`Path.group`
-:func:`os.path.isabs` :meth:`PurePath.is_absolute`
-:func:`os.path.join` :func:`PurePath.joinpath`
-:func:`os.path.basename` :attr:`PurePath.name`
-:func:`os.path.dirname` :attr:`PurePath.parent`
-:func:`os.path.samefile` :meth:`Path.samefile`
-:func:`os.path.splitext` :attr:`PurePath.stem` and
- :attr:`PurePath.suffix`
-==================================== ==============================
+===================================== ==============================================
+:mod:`os` and :mod:`os.path` :mod:`pathlib`
+===================================== ==============================================
+:func:`os.path.dirname` :attr:`PurePath.parent`
+:func:`os.path.basename` :attr:`PurePath.name`
+:func:`os.path.splitext` :attr:`PurePath.stem`, :attr:`PurePath.suffix`
+:func:`os.path.join` :meth:`PurePath.joinpath`
+:func:`os.path.isabs` :meth:`PurePath.is_absolute`
+:func:`os.path.relpath` :meth:`PurePath.relative_to` [1]_
+:func:`os.path.expanduser` :meth:`Path.expanduser` [2]_
+:func:`os.path.realpath` :meth:`Path.resolve`
+:func:`os.path.abspath` :meth:`Path.absolute` [3]_
+:func:`os.path.exists` :meth:`Path.exists`
+:func:`os.path.isfile` :meth:`Path.is_file`
+:func:`os.path.isdir` :meth:`Path.is_dir`
+:func:`os.path.islink` :meth:`Path.is_symlink`
+:func:`os.path.isjunction` :meth:`Path.is_junction`
+:func:`os.path.ismount` :meth:`Path.is_mount`
+:func:`os.path.samefile` :meth:`Path.samefile`
+:func:`os.getcwd` :meth:`Path.cwd`
+:func:`os.stat` :meth:`Path.stat`
+:func:`os.lstat` :meth:`Path.lstat`
+:func:`os.listdir` :meth:`Path.iterdir`
+:func:`os.walk` :meth:`Path.walk` [4]_
+:func:`os.mkdir`, :func:`os.makedirs` :meth:`Path.mkdir`
+:func:`os.link` :meth:`Path.hardlink_to`
+:func:`os.symlink` :meth:`Path.symlink_to`
+:func:`os.readlink` :meth:`Path.readlink`
+:func:`os.rename` :meth:`Path.rename`
+:func:`os.replace` :meth:`Path.replace`
+:func:`os.remove`, :func:`os.unlink` :meth:`Path.unlink`
+:func:`os.rmdir` :meth:`Path.rmdir`
+:func:`os.chmod` :meth:`Path.chmod`
+:func:`os.lchmod` :meth:`Path.lchmod`
+===================================== ==============================================
.. rubric:: Footnotes
-.. [#] :func:`os.path.abspath` normalizes the resulting path, which may change its meaning in the presence of symlinks, while :meth:`Path.absolute` does not.
-.. [#] :meth:`PurePath.relative_to` requires ``self`` to be the subpath of the argument, but :func:`os.path.relpath` does not.
+.. [1] :func:`os.path.relpath` calls :func:`~os.path.abspath` to make paths
+ absolute and remove "``..``" parts, whereas :meth:`PurePath.relative_to`
+ is a lexical operation that raises :exc:`ValueError` when its inputs'
+ anchors differ (e.g. if one path is absolute and the other relative.)
+.. [2] :func:`os.path.expanduser` returns the path unchanged if the home
+ directory can't be resolved, whereas :meth:`Path.expanduser` raises
+ :exc:`RuntimeError`.
+.. [3] :func:`os.path.abspath` removes "``..``" components without resolving
+ symlinks, which may change the meaning of the path, whereas
+ :meth:`Path.absolute` leaves any "``..``" components in the path.
+.. [4] :func:`os.walk` always follows symlinks when categorizing paths into
+ *dirnames* and *filenames*, whereas :meth:`Path.walk` categorizes all
+ symlinks into *filenames* when *follow_symlinks* is false (the default.)
diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst
index 5d4ff34ba029a0..f095cc84173737 100644
--- a/Doc/library/pkgutil.rst
+++ b/Doc/library/pkgutil.rst
@@ -34,9 +34,9 @@ support.
*name* argument. This feature is similar to :file:`\*.pth` files (see the
:mod:`site` module for more information), except that it doesn't special-case
lines starting with ``import``. A :file:`\*.pkg` file is trusted at face
- value: apart from checking for duplicates, all entries found in a
- :file:`\*.pkg` file are added to the path, regardless of whether they exist
- on the filesystem. (This is a feature.)
+ value: apart from skipping blank lines and ignoring comments, all entries
+ found in a :file:`\*.pkg` file are added to the path, regardless of whether
+ they exist on the filesystem (this is a feature).
If the input path is not a list (as is the case for frozen packages) it is
returned unchanged. The input path is not modified; an extended copy is
diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst
index df706c10ce9ec4..1b3498e51f766d 100644
--- a/Doc/library/pprint.rst
+++ b/Doc/library/pprint.rst
@@ -35,24 +35,66 @@ Dictionaries are sorted by key before the display is computed.
Functions
---------
-.. function:: pp(object, *args, sort_dicts=False, **kwargs)
-
- Prints the formatted representation of *object* followed by a newline.
- If *sort_dicts* is false (the default), dictionaries will be displayed with
- their keys in insertion order, otherwise the dict keys will be sorted.
- *args* and *kwargs* will be passed to :func:`~pprint.pprint` as formatting
- parameters.
-
- >>> import pprint
- >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
- >>> stuff.insert(0, stuff)
- >>> pprint.pp(stuff)
- [,
- 'spam',
- 'eggs',
- 'lumberjack',
- 'knights',
- 'ni']
+.. function:: pp(object, stream=None, indent=1, width=80, depth=None, *, \
+ compact=False, sort_dicts=False, underscore_numbers=False)
+
+ Prints the formatted representation of *object*, followed by a newline.
+ This function may be used in the interactive interpreter
+ instead of the :func:`print` function for inspecting values.
+ Tip: you can reassign ``print = pprint.pp`` for use within a scope.
+
+ :param object:
+ The object to be printed.
+
+ :param stream:
+ A file-like object to which the output will be written
+ by calling its :meth:`!write` method.
+ If ``None`` (the default), :data:`sys.stdout` is used.
+ :type stream: :term:`file-like object` | None
+
+ :param int indent:
+ The amount of indentation added for each nesting level.
+
+ :param int width:
+ The desired maximum number of characters per line in the output.
+ If a structure cannot be formatted within the width constraint,
+ a best effort will be made.
+
+ :param depth:
+ The number of nesting levels which may be printed.
+ If the data structure being printed is too deep,
+ the next contained level is replaced by ``...``.
+ If ``None`` (the default), there is no constraint
+ on the depth of the objects being formatted.
+ :type depth: int | None
+
+ :param bool compact:
+ Control the way long :term:`sequences ` are formatted.
+ If ``False`` (the default),
+ each item of a sequence will be formatted on a separate line,
+ otherwise as many items as will fit within the *width*
+ will be formatted on each output line.
+
+ :param bool sort_dicts:
+ If ``True``, dictionaries will be formatted with
+ their keys sorted, otherwise
+ they will be displayed in insertion order (the default).
+
+ :param bool underscore_numbers:
+ If ``True``,
+ integers will be formatted with the ``_`` character for a thousands separator,
+ otherwise underscores are not displayed (the default).
+
+ >>> import pprint
+ >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
+ >>> stuff.insert(0, stuff)
+ >>> pprint.pp(stuff)
+ [,
+ 'spam',
+ 'eggs',
+ 'lumberjack',
+ 'knights',
+ 'ni']
.. versionadded:: 3.8
@@ -60,19 +102,10 @@ Functions
.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \
compact=False, sort_dicts=True, underscore_numbers=False)
- Prints the formatted representation of *object* on *stream*, followed by a
- newline. If *stream* is ``None``, :data:`sys.stdout` is used. This may be used
- in the interactive interpreter instead of the :func:`print` function for
- inspecting values (you can even reassign ``print = pprint.pprint`` for use
- within a scope).
-
- The configuration parameters *stream*, *indent*, *width*, *depth*,
- *compact*, *sort_dicts* and *underscore_numbers* are passed to the
- :class:`PrettyPrinter` constructor and their meanings are as
- described in its documentation below.
+ Alias for :func:`~pprint.pp` with *sort_dicts* set to ``True`` by default,
+ which would automatically sort the dictionaries' keys,
+ you might want to use :func:`~pprint.pp` instead where it is ``False`` by default.
- Note that *sort_dicts* is ``True`` by default and you might want to use
- :func:`~pprint.pp` instead where it is ``False`` by default.
.. function:: pformat(object, indent=1, width=80, depth=None, *, \
compact=False, sort_dicts=True, underscore_numbers=False)
@@ -80,7 +113,7 @@ Functions
Return the formatted representation of *object* as a string. *indent*,
*width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* are
passed to the :class:`PrettyPrinter` constructor as formatting parameters
- and their meanings are as described in its documentation below.
+ and their meanings are as described in the documentation above.
.. function:: isreadable(object)
@@ -119,51 +152,39 @@ Functions
PrettyPrinter Objects
---------------------
-This module defines one class:
-
-.. First the implementation class:
-
-
.. index:: single: ...; placeholder
.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \
compact=False, sort_dicts=True, underscore_numbers=False)
- Construct a :class:`PrettyPrinter` instance. This constructor understands
- several keyword parameters.
-
- *stream* (default :data:`!sys.stdout`) is a :term:`file-like object` to
- which the output will be written by calling its :meth:`!write` method.
- If both *stream* and :data:`!sys.stdout` are ``None``, then
- :meth:`~PrettyPrinter.pprint` silently returns.
+ Construct a :class:`PrettyPrinter` instance.
- Other values configure the manner in which nesting of complex data
- structures is displayed.
+ Arguments have the same meaning as for :func:`~pprint.pp`.
+ Note that they are in a different order, and that *sort_dicts* defaults to ``True``.
- *indent* (default 1) specifies the amount of indentation added for
- each nesting level.
-
- *depth* controls the number of nesting levels which may be printed; if
- the data structure being printed is too deep, the next contained level
- is replaced by ``...``. By default, there is no constraint on the
- depth of the objects being formatted.
-
- *width* (default 80) specifies the desired maximum number of characters per
- line in the output. If a structure cannot be formatted within the width
- constraint, a best effort will be made.
-
- *compact* impacts the way that long sequences (lists, tuples, sets, etc)
- are formatted. If *compact* is false (the default) then each item of a
- sequence will be formatted on a separate line. If *compact* is true, as
- many items as will fit within the *width* will be formatted on each output
- line.
-
- If *sort_dicts* is true (the default), dictionaries will be formatted with
- their keys sorted, otherwise they will display in insertion order.
+ >>> import pprint
+ >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
+ >>> stuff.insert(0, stuff[:])
+ >>> pp = pprint.PrettyPrinter(indent=4)
+ >>> pp.pprint(stuff)
+ [ ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
+ 'spam',
+ 'eggs',
+ 'lumberjack',
+ 'knights',
+ 'ni']
+ >>> pp = pprint.PrettyPrinter(width=41, compact=True)
+ >>> pp.pprint(stuff)
+ [['spam', 'eggs', 'lumberjack',
+ 'knights', 'ni'],
+ 'spam', 'eggs', 'lumberjack', 'knights',
+ 'ni']
+ >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
+ ... ('parrot', ('fresh fruit',))))))))
+ >>> pp = pprint.PrettyPrinter(depth=6)
+ >>> pp.pprint(tup)
+ ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))
- If *underscore_numbers* is true, integers will be formatted with the
- ``_`` character for a thousands separator, otherwise underscores are not
- displayed (the default).
.. versionchanged:: 3.4
Added the *compact* parameter.
@@ -177,29 +198,6 @@ This module defines one class:
.. versionchanged:: 3.11
No longer attempts to write to :data:`!sys.stdout` if it is ``None``.
- >>> import pprint
- >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
- >>> stuff.insert(0, stuff[:])
- >>> pp = pprint.PrettyPrinter(indent=4)
- >>> pp.pprint(stuff)
- [ ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
- 'spam',
- 'eggs',
- 'lumberjack',
- 'knights',
- 'ni']
- >>> pp = pprint.PrettyPrinter(width=41, compact=True)
- >>> pp.pprint(stuff)
- [['spam', 'eggs', 'lumberjack',
- 'knights', 'ni'],
- 'spam', 'eggs', 'lumberjack', 'knights',
- 'ni']
- >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
- ... ('parrot', ('fresh fruit',))))))))
- >>> pp = pprint.PrettyPrinter(depth=6)
- >>> pp.pprint(tup)
- ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))
-
:class:`PrettyPrinter` instances have the following methods:
diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst
index cc059b66fcb84b..b89655ea472dee 100644
--- a/Doc/library/profile.rst
+++ b/Doc/library/profile.rst
@@ -675,7 +675,7 @@ you are using :class:`profile.Profile` or :class:`cProfile.Profile`,
that you choose (see :ref:`profile-calibration`). For most machines, a timer
that returns a lone integer value will provide the best results in terms of
low overhead during profiling. (:func:`os.times` is *pretty* bad, as it
- returns a tuple of floating point values). If you want to substitute a
+ returns a tuple of floating-point values). If you want to substitute a
better timer in the cleanest fashion, derive a class and hardwire a
replacement dispatch method that best handles your timer call, along with the
appropriate calibration constant.
@@ -692,7 +692,7 @@ you are using :class:`profile.Profile` or :class:`cProfile.Profile`,
As the :class:`cProfile.Profile` class cannot be calibrated, custom timer
functions should be used with care and should be as fast as possible. For
the best results with a custom timer, it might be necessary to hard-code it
- in the C source of the internal :mod:`_lsprof` module.
+ in the C source of the internal :mod:`!_lsprof` module.
Python 3.3 adds several new functions in :mod:`time` that can be used to make
precise measurements of process or wall-clock time. For example, see
diff --git a/Doc/library/random.rst b/Doc/library/random.rst
index 10c88ac68a81aa..a589bf76b5c2a7 100644
--- a/Doc/library/random.rst
+++ b/Doc/library/random.rst
@@ -194,8 +194,8 @@ Functions for sequences
For a given seed, the :func:`choices` function with equal weighting
typically produces a different sequence than repeated calls to
- :func:`choice`. The algorithm used by :func:`choices` uses floating
- point arithmetic for internal consistency and speed. The algorithm used
+ :func:`choice`. The algorithm used by :func:`choices` uses floating-point
+ arithmetic for internal consistency and speed. The algorithm used
by :func:`choice` defaults to integer arithmetic with repeated selections
to avoid small biases from round-off error.
@@ -292,12 +292,12 @@ be found in any statistics text.
.. function:: random()
- Return the next random floating point number in the range ``0.0 <= X < 1.0``
+ Return the next random floating-point number in the range ``0.0 <= X < 1.0``
.. function:: uniform(a, b)
- Return a random floating point number *N* such that ``a <= N <= b`` for
+ Return a random floating-point number *N* such that ``a <= N <= b`` for
``a <= b`` and ``b <= N <= a`` for ``b < a``.
The end-point value ``b`` may or may not be included in the range
@@ -307,7 +307,7 @@ be found in any statistics text.
.. function:: triangular(low, high, mode)
- Return a random floating point number *N* such that ``low <= N <= high`` and
+ Return a random floating-point number *N* such that ``low <= N <= high`` and
with the specified *mode* between those bounds. The *low* and *high* bounds
default to zero and one. The *mode* argument defaults to the midpoint
between the bounds, giving a symmetric distribution.
diff --git a/Doc/library/re.rst b/Doc/library/re.rst
index 220bd687bc112d..813afcc483a28e 100644
--- a/Doc/library/re.rst
+++ b/Doc/library/re.rst
@@ -101,7 +101,7 @@ The special characters are:
``.``
(Dot.) In the default mode, this matches any character except a newline. If
the :const:`DOTALL` flag has been specified, this matches any character
- including a newline.
+ including a newline. ``(?s:.)`` matches any character regardless of flags.
.. index:: single: ^ (caret); in regular expressions
@@ -911,6 +911,10 @@ Functions
``None`` if no position in the string matches the pattern; note that this is
different from finding a zero-length match at some point in the string.
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. function:: match(pattern, string, flags=0)
@@ -925,6 +929,10 @@ Functions
If you want to locate a match anywhere in *string*, use :func:`search`
instead (see also :ref:`search-vs-match`).
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. function:: fullmatch(pattern, string, flags=0)
@@ -932,6 +940,10 @@ Functions
corresponding :class:`~re.Match`. Return ``None`` if the string does not match
the pattern; note that this is different from a zero-length match.
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. versionadded:: 3.4
@@ -974,6 +986,10 @@ Functions
>>> re.split(r'(\W*)', '...words...')
['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. versionchanged:: 3.1
Added the optional flags argument.
@@ -999,6 +1015,10 @@ Functions
>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
[('width', '20'), ('height', '10')]
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. versionchanged:: 3.7
Non-empty matches can now start just after a previous empty match.
@@ -1010,6 +1030,10 @@ Functions
is scanned left-to-right, and matches are returned in the order found. Empty
matches are included in the result.
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. versionchanged:: 3.7
Non-empty matches can now start just after a previous empty match.
@@ -1065,6 +1089,10 @@ Functions
character ``'0'``. The backreference ``\g<0>`` substitutes in the entire
substring matched by the RE.
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. versionchanged:: 3.1
Added the optional flags argument.
@@ -1100,6 +1128,10 @@ Functions
.. versionchanged:: 3.5
Unmatched groups are replaced with an empty string.
+ The expression's behaviour can be modified by specifying a *flags* value.
+ Values can be any of the `flags`_ variables, combined using bitwise OR
+ (the ``|`` operator).
+
.. function:: escape(pattern)
diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst
index 43cf8d5cdac544..f02aec8a6a8105 100644
--- a/Doc/library/readline.rst
+++ b/Doc/library/readline.rst
@@ -44,6 +44,10 @@ Readline library in general.
python:bind -v
python:bind ^I rl_complete
+ Also note that different libraries may use different history file formats.
+ When switching the underlying library, existing history files may become
+ unusable.
+
Init file
---------
diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst
index 7465bc5402ca57..02009d8210447e 100644
--- a/Doc/library/resource.rst
+++ b/Doc/library/resource.rst
@@ -305,7 +305,7 @@ These functions are used to retrieve resource usage information:
elements.
The fields :attr:`ru_utime` and :attr:`ru_stime` of the return value are
- floating point values representing the amount of time spent executing in user
+ floating-point values representing the amount of time spent executing in user
mode and the amount of time spent executing in system mode, respectively. The
remaining values are integers. Consult the :manpage:`getrusage(2)` man page for
detailed information about these values. A brief summary is presented here:
diff --git a/Doc/library/select.rst b/Doc/library/select.rst
index 06ebaf0201e0e7..f23a249f44b485 100644
--- a/Doc/library/select.rst
+++ b/Doc/library/select.rst
@@ -129,7 +129,7 @@ The module defines the following:
Empty iterables are allowed, but acceptance of three empty iterables is
platform-dependent. (It is known to work on Unix but not on Windows.) The
- optional *timeout* argument specifies a time-out as a floating point number
+ optional *timeout* argument specifies a time-out as a floating-point number
in seconds. When the *timeout* argument is omitted the function blocks until
at least one file descriptor is ready. A time-out value of zero specifies a
poll and never blocks.
diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst
index 2511ef7f2ada41..7cd530a5fd6438 100644
--- a/Doc/library/smtplib.rst
+++ b/Doc/library/smtplib.rst
@@ -556,34 +556,33 @@ This example prompts the user for addresses needed in the message envelope ('To'
and 'From' addresses), and the message to be delivered. Note that the headers
to be included with the message must be included in the message as entered; this
example doesn't do any processing of the :rfc:`822` headers. In particular, the
-'To' and 'From' addresses must be included in the message headers explicitly. ::
+'To' and 'From' addresses must be included in the message headers explicitly::
import smtplib
- def prompt(prompt):
- return input(prompt).strip()
+ def prompt(title):
+ return input(title).strip()
- fromaddr = prompt("From: ")
- toaddrs = prompt("To: ").split()
+ from_addr = prompt("From: ")
+ to_addrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")
# Add the From: and To: headers at the start!
- msg = ("From: %s\r\nTo: %s\r\n\r\n"
- % (fromaddr, ", ".join(toaddrs)))
+ lines = [f"From: {from_addr}", f"To: {', '.join(to_addrs)}", ""]
while True:
try:
line = input()
except EOFError:
break
- if not line:
- break
- msg = msg + line
+ else:
+ lines.append(line)
+ msg = "\r\n".join(lines)
print("Message length is", len(msg))
- server = smtplib.SMTP('localhost')
+ server = smtplib.SMTP("localhost")
server.set_debuglevel(1)
- server.sendmail(fromaddr, toaddrs, msg)
+ server.sendmail(from_addr, to_addrs, msg)
server.quit()
.. note::
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index 10f03b3fe0274e..8389d67860d453 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -1917,7 +1917,7 @@ to sockets.
.. method:: socket.settimeout(value)
Set a timeout on blocking socket operations. The *value* argument can be a
- nonnegative floating point number expressing seconds, or ``None``.
+ nonnegative floating-point number expressing seconds, or ``None``.
If a non-zero value is given, subsequent socket operations will raise a
:exc:`timeout` exception if the timeout period *value* has elapsed before
the operation has completed. If zero is given, the socket is put in
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index 8fb0d5056c117d..d7a84733f86b4c 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -1428,6 +1428,19 @@ to speed up repeated connections from the same clients.
:data:`PROTOCOL_TLS`, :data:`PROTOCOL_TLS_CLIENT`, and
:data:`PROTOCOL_TLS_SERVER` use TLS 1.2 as minimum TLS version.
+ .. note::
+
+ :class:`SSLContext` only supports limited mutation once it has been used
+ by a connection. Adding new certificates to the internal trust store is
+ allowed, but changing ciphers, verification settings, or mTLS
+ certificates may result in surprising behavior.
+
+ .. note::
+
+ :class:`SSLContext` is designed to be shared and used by multiple
+ connections.
+ Thus, it is thread-safe as long as it is not reconfigured after being
+ used by a connection.
:class:`SSLContext` objects have the following methods and attributes:
@@ -1684,7 +1697,7 @@ to speed up repeated connections from the same clients.
IDN-encoded internationalized domain name, the *server_name_callback*
receives a decoded U-label (``"pythön.org"``).
- If there is an decoding error on the server name, the TLS connection will
+ If there is a decoding error on the server name, the TLS connection will
terminate with an :const:`ALERT_DESCRIPTION_INTERNAL_ERROR` fatal TLS
alert message to the client.
@@ -2556,7 +2569,7 @@ Verifying certificates
When calling the :class:`SSLContext` constructor directly,
:const:`CERT_NONE` is the default. Since it does not authenticate the other
-peer, it can be insecure, especially in client mode where most of time you
+peer, it can be insecure, especially in client mode where most of the time you
would like to ensure the authenticity of the server you're talking to.
Therefore, when in client mode, it is highly recommended to use
:const:`CERT_REQUIRED`. However, it is in itself not sufficient; you also
diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst
index 6da3bced99dffa..ce1b8a112e852b 100644
--- a/Doc/library/statistics.rst
+++ b/Doc/library/statistics.rst
@@ -73,7 +73,7 @@ or sample.
======================= ===============================================================
:func:`mean` Arithmetic mean ("average") of data.
-:func:`fmean` Fast, floating point arithmetic mean, with optional weighting.
+:func:`fmean` Fast, floating-point arithmetic mean, with optional weighting.
:func:`geometric_mean` Geometric mean of data.
:func:`harmonic_mean` Harmonic mean of data.
:func:`median` Median (middle value) of data.
@@ -408,6 +408,12 @@ However, for reading convenience, most of the examples show sorted sequences.
>>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
'red'
+ Only hashable inputs are supported. To handle type :class:`set`,
+ consider casting to :class:`frozenset`. To handle type :class:`list`,
+ consider casting to :class:`tuple`. For mixed or nested inputs, consider
+ using this slower quadratic algorithm that only depends on equality tests:
+ ``max(data, key=data.count)``.
+
.. versionchanged:: 3.8
Now handles multimodal datasets by returning the first mode encountered.
Formerly, it raised :exc:`StatisticsError` when more than one mode was
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index d11bfb803f8c56..02dcf0321be21e 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -209,18 +209,18 @@ Numeric Types --- :class:`int`, :class:`float`, :class:`complex`
pair: object; numeric
pair: object; Boolean
pair: object; integer
- pair: object; floating point
+ pair: object; floating-point
pair: object; complex number
pair: C; language
-There are three distinct numeric types: :dfn:`integers`, :dfn:`floating
-point numbers`, and :dfn:`complex numbers`. In addition, Booleans are a
-subtype of integers. Integers have unlimited precision. Floating point
+There are three distinct numeric types: :dfn:`integers`, :dfn:`floating-point
+numbers`, and :dfn:`complex numbers`. In addition, Booleans are a
+subtype of integers. Integers have unlimited precision. Floating-point
numbers are usually implemented using :c:expr:`double` in C; information
-about the precision and internal representation of floating point
+about the precision and internal representation of floating-point
numbers for the machine on which your program is running is available
in :data:`sys.float_info`. Complex numbers have a real and imaginary
-part, which are each a floating point number. To extract these parts
+part, which are each a floating-point number. To extract these parts
from a complex number *z*, use ``z.real`` and ``z.imag``. (The standard
library includes the additional numeric types :mod:`fractions.Fraction`, for
rationals, and :mod:`decimal.Decimal`, for floating-point numbers with
@@ -229,7 +229,7 @@ user-definable precision.)
.. index::
pair: numeric; literals
pair: integer; literals
- pair: floating point; literals
+ pair: floating-point; literals
pair: complex number; literals
pair: hexadecimal; literals
pair: octal; literals
@@ -238,7 +238,7 @@ user-definable precision.)
Numbers are created by numeric literals or as the result of built-in functions
and operators. Unadorned integer literals (including hex, octal and binary
numbers) yield integers. Numeric literals containing a decimal point or an
-exponent sign yield floating point numbers. Appending ``'j'`` or ``'J'`` to a
+exponent sign yield floating-point numbers. Appending ``'j'`` or ``'J'`` to a
numeric literal yields an imaginary number (a complex number with a zero real
part) which you can add to an integer or float to get a complex number with real
and imaginary parts.
@@ -1220,7 +1220,7 @@ accepts integers that meet the value restriction ``0 <= x <= 255``).
Notes:
(1)
- *t* must have the same length as the slice it is replacing.
+ If *k* is not equal to ``1``, *t* must have the same length as the slice it is replacing.
(2)
The optional argument *i* defaults to ``-1``, so that by default the last
@@ -1497,8 +1497,8 @@ objects that compare equal might have different :attr:`~range.start`,
.. seealso::
* The `linspace recipe `_
- shows how to implement a lazy version of range suitable for floating
- point applications.
+ shows how to implement a lazy version of range suitable for floating-point
+ applications.
.. index::
single: string; text sequence type
@@ -2092,8 +2092,9 @@ expression support in the :mod:`re` module).
If *sep* is given, consecutive delimiters are not grouped together and are
deemed to delimit empty strings (for example, ``'1,,2'.split(',')`` returns
``['1', '', '2']``). The *sep* argument may consist of multiple characters
- (for example, ``'1<>2<>3'.split('<>')`` returns ``['1', '2', '3']``).
- Splitting an empty string with a specified separator returns ``['']``.
+ as a single delimiter (to split with multiple delimiters, use
+ :func:`re.split`). Splitting an empty string with a specified separator
+ returns ``['']``.
For example::
@@ -2103,6 +2104,8 @@ expression support in the :mod:`re` module).
['1', '2,3']
>>> '1,2,,3,'.split(',')
['1', '2', '', '3', '']
+ >>> '1<>2<>3<4'.split('<>')
+ ['1', '2', '3<4']
If *sep* is not specified or is ``None``, a different splitting algorithm is
applied: runs of consecutive whitespace are regarded as a single separator,
@@ -2430,19 +2433,19 @@ The conversion types are:
+------------+-----------------------------------------------------+-------+
| ``'X'`` | Signed hexadecimal (uppercase). | \(2) |
+------------+-----------------------------------------------------+-------+
-| ``'e'`` | Floating point exponential format (lowercase). | \(3) |
+| ``'e'`` | Floating-point exponential format (lowercase). | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'E'`` | Floating point exponential format (uppercase). | \(3) |
+| ``'E'`` | Floating-point exponential format (uppercase). | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'f'`` | Floating point decimal format. | \(3) |
+| ``'f'`` | Floating-point decimal format. | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'F'`` | Floating point decimal format. | \(3) |
+| ``'F'`` | Floating-point decimal format. | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'g'`` | Floating point format. Uses lowercase exponential | \(4) |
+| ``'g'`` | Floating-point format. Uses lowercase exponential | \(4) |
| | format if exponent is less than -4 or not less than | |
| | precision, decimal format otherwise. | |
+------------+-----------------------------------------------------+-------+
-| ``'G'`` | Floating point format. Uses uppercase exponential | \(4) |
+| ``'G'`` | Floating-point format. Uses uppercase exponential | \(4) |
| | format if exponent is less than -4 or not less than | |
| | precision, decimal format otherwise. | |
+------------+-----------------------------------------------------+-------+
@@ -3140,10 +3143,9 @@ produce new objects.
If *sep* is given, consecutive delimiters are not grouped together and are
deemed to delimit empty subsequences (for example, ``b'1,,2'.split(b',')``
returns ``[b'1', b'', b'2']``). The *sep* argument may consist of a
- multibyte sequence (for example, ``b'1<>2<>3'.split(b'<>')`` returns
- ``[b'1', b'2', b'3']``). Splitting an empty sequence with a specified
- separator returns ``[b'']`` or ``[bytearray(b'')]`` depending on the type
- of object being split. The *sep* argument may be any
+ multibyte sequence as a single delimiter. Splitting an empty sequence with
+ a specified separator returns ``[b'']`` or ``[bytearray(b'')]`` depending
+ on the type of object being split. The *sep* argument may be any
:term:`bytes-like object`.
For example::
@@ -3154,6 +3156,8 @@ produce new objects.
[b'1', b'2,3']
>>> b'1,2,,3,'.split(b',')
[b'1', b'2', b'', b'3', b'']
+ >>> b'1<>2<>3<4'.split(b'<>')
+ [b'1', b'2', b'3<4']
If *sep* is not specified or is ``None``, a different splitting algorithm
is applied: runs of consecutive ASCII whitespace are regarded as a single
@@ -3648,19 +3652,19 @@ The conversion types are:
+------------+-----------------------------------------------------+-------+
| ``'X'`` | Signed hexadecimal (uppercase). | \(2) |
+------------+-----------------------------------------------------+-------+
-| ``'e'`` | Floating point exponential format (lowercase). | \(3) |
+| ``'e'`` | Floating-point exponential format (lowercase). | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'E'`` | Floating point exponential format (uppercase). | \(3) |
+| ``'E'`` | Floating-point exponential format (uppercase). | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'f'`` | Floating point decimal format. | \(3) |
+| ``'f'`` | Floating-point decimal format. | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'F'`` | Floating point decimal format. | \(3) |
+| ``'F'`` | Floating-point decimal format. | \(3) |
+------------+-----------------------------------------------------+-------+
-| ``'g'`` | Floating point format. Uses lowercase exponential | \(4) |
+| ``'g'`` | Floating-point format. Uses lowercase exponential | \(4) |
| | format if exponent is less than -4 or not less than | |
| | precision, decimal format otherwise. | |
+------------+-----------------------------------------------------+-------+
-| ``'G'`` | Floating point format. Uses uppercase exponential | \(4) |
+| ``'G'`` | Floating-point format. Uses uppercase exponential | \(4) |
| | format if exponent is less than -4 or not less than | |
| | precision, decimal format otherwise. | |
+------------+-----------------------------------------------------+-------+
@@ -3882,7 +3886,7 @@ copying.
>>> a == b
False
- Note that, as with floating point numbers, ``v is w`` does *not* imply
+ Note that, as with floating-point numbers, ``v is w`` does *not* imply
``v == w`` for memoryview objects.
.. versionchanged:: 3.3
@@ -4556,7 +4560,7 @@ can be used interchangeably to index the same dictionary entry.
Return a shallow copy of the dictionary.
- .. classmethod:: fromkeys(iterable, value=None)
+ .. classmethod:: fromkeys(iterable, value=None, /)
Create a new dictionary with keys from *iterable* and values set to *value*.
diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index c3c0d732cf18d4..1f316307965c11 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -418,7 +418,7 @@ instead.
.. index:: single: _ (underscore); in string formatting
The ``'_'`` option signals the use of an underscore for a thousands
-separator for floating point presentation types and for integer
+separator for floating-point presentation types and for integer
presentation type ``'d'``. For integer presentation types ``'b'``,
``'o'``, ``'x'``, and ``'X'``, underscores will be inserted every 4
digits. For other presentation types, specifying this option is an
@@ -491,9 +491,9 @@ The available integer presentation types are:
+---------+----------------------------------------------------------+
In addition to the above presentation types, integers can be formatted
-with the floating point presentation types listed below (except
+with the floating-point presentation types listed below (except
``'n'`` and ``None``). When doing so, :func:`float` is used to convert the
-integer to a floating point number before formatting.
+integer to a floating-point number before formatting.
The available presentation types for :class:`float` and
:class:`~decimal.Decimal` values are:
diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst
index 33f96a2f744902..b7e25a742f8d6b 100644
--- a/Doc/library/subprocess.rst
+++ b/Doc/library/subprocess.rst
@@ -1110,7 +1110,7 @@ The :mod:`subprocess` module exposes the following constants.
.. data:: NORMAL_PRIORITY_CLASS
A :class:`Popen` ``creationflags`` parameter to specify that a new process
- will have an normal priority. (default)
+ will have a normal priority. (default)
.. versionadded:: 3.7
diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst
index fc2d79b77cf5a2..de9a961592ace7 100644
--- a/Doc/library/symtable.rst
+++ b/Doc/library/symtable.rst
@@ -127,8 +127,39 @@ Examining Symbol Tables
.. method:: get_methods()
- Return a tuple containing the names of methods declared in the class.
-
+ Return a tuple containing the names of method-like functions declared
+ in the class.
+
+ Here, the term 'method' designates *any* function defined in the class
+ body via :keyword:`def` or :keyword:`async def`.
+
+ Functions defined in a deeper scope (e.g., in an inner class) are not
+ picked up by :meth:`get_methods`.
+
+ For example:
+
+ >>> import symtable
+ >>> st = symtable.symtable('''
+ ... def outer(): pass
+ ...
+ ... class A:
+ ... def f():
+ ... def w(): pass
+ ...
+ ... def g(self): pass
+ ...
+ ... @classmethod
+ ... async def h(cls): pass
+ ...
+ ... global outer
+ ... def outer(self): pass
+ ... ''', 'test', 'exec')
+ >>> class_A = st.get_children()[1]
+ >>> class_A.get_methods()
+ ('f', 'g', 'h')
+
+ Although ``A().f()`` raises :exc:`TypeError` at runtime, ``A.f`` is still
+ considered as a method-like function.
.. class:: Symbol
diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst
index 75672913943c21..b9841d49be2878 100644
--- a/Doc/library/sysconfig.rst
+++ b/Doc/library/sysconfig.rst
@@ -376,7 +376,7 @@ Other functions
This is used mainly to distinguish platform-specific build directories and
platform-specific built distributions. Typically includes the OS name and
- version and the architecture (as supplied by 'os.uname()'), although the
+ version and the architecture (as supplied by :func:`os.uname`), although the
exact information included depends on the OS; e.g., on Linux, the kernel
version isn't particularly important.
diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst
index c88dcabcd91eb7..5d94a7760f9f56 100644
--- a/Doc/library/threading.rst
+++ b/Doc/library/threading.rst
@@ -409,7 +409,7 @@ since it is impossible to detect the termination of alien threads.
timeout occurs.
When the *timeout* argument is present and not ``None``, it should be a
- floating point number specifying a timeout for the operation in seconds
+ floating-point number specifying a timeout for the operation in seconds
(or fractions thereof). As :meth:`~Thread.join` always returns ``None``,
you must call :meth:`~Thread.is_alive` after :meth:`~Thread.join` to
decide whether a timeout happened -- if the thread is still alive, the
@@ -790,7 +790,7 @@ item to the buffer only needs to wake up one consumer thread.
occurs. Once awakened or timed out, it re-acquires the lock and returns.
When the *timeout* argument is present and not ``None``, it should be a
- floating point number specifying a timeout for the operation in seconds
+ floating-point number specifying a timeout for the operation in seconds
(or fractions thereof).
When the underlying lock is an :class:`RLock`, it is not released using
@@ -1014,10 +1014,10 @@ method. The :meth:`~Event.wait` method blocks until the flag is true.
has not expired. The return value represents the
reason that this blocking method returned; ``True`` if returning because
the internal flag is set to true, or ``False`` if a timeout is given and
- the the internal flag did not become true within the given wait time.
+ the internal flag did not become true within the given wait time.
When the timeout argument is present and not ``None``, it should be a
- floating point number specifying a timeout for the operation in seconds,
+ floating-point number specifying a timeout for the operation in seconds,
or fractions thereof.
.. versionchanged:: 3.1
diff --git a/Doc/library/time.rst b/Doc/library/time.rst
index d792d5633dd6e0..188dbca8fd1691 100644
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -69,7 +69,7 @@ An explanation of some terminology and conventions is in order.
systems, the clock "ticks" only 50 or 100 times a second.
* On the other hand, the precision of :func:`.time` and :func:`sleep` is better
- than their Unix equivalents: times are expressed as floating point numbers,
+ than their Unix equivalents: times are expressed as floating-point numbers,
:func:`.time` returns the most accurate time available (using Unix
:c:func:`!gettimeofday` where available), and :func:`sleep` will accept a time
with a nonzero fraction (Unix :c:func:`!select` is used to implement this, where
@@ -273,7 +273,7 @@ Functions
This is the inverse function of :func:`localtime`. Its argument is the
:class:`struct_time` or full 9-tuple (since the dst flag is needed; use ``-1``
as the dst flag if it is unknown) which expresses the time in *local* time, not
- UTC. It returns a floating point number, for compatibility with :func:`.time`.
+ UTC. It returns a floating-point number, for compatibility with :func:`.time`.
If the input value cannot be represented as a valid time, either
:exc:`OverflowError` or :exc:`ValueError` will be raised (which depends on
whether the invalid value is caught by Python or the underlying C libraries).
@@ -358,7 +358,7 @@ Functions
.. function:: sleep(secs)
Suspend execution of the calling thread for the given number of seconds.
- The argument may be a floating point number to indicate a more precise sleep
+ The argument may be a floating-point number to indicate a more precise sleep
time.
If the sleep is interrupted by a signal and no exception is raised by the
@@ -642,13 +642,13 @@ Functions
.. function:: time() -> float
- Return the time in seconds since the epoch_ as a floating point
+ Return the time in seconds since the epoch_ as a floating-point
number. The handling of `leap seconds`_ is platform dependent.
On Windows and most Unix systems, the leap seconds are not counted towards
the time in seconds since the epoch_. This is commonly referred to as `Unix
time `_.
- Note that even though the time is always returned as a floating point
+ Note that even though the time is always returned as a floating-point
number, not all systems provide time with a better precision than 1 second.
While this function normally returns non-decreasing values, it can return a
lower value than a previous call if the system clock has been set back
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 1a5c21d3c94304..83956a6a9fb956 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -27,12 +27,13 @@ This module provides runtime support for type hints.
Consider the function below::
- def moon_weight(earth_weight: float) -> str:
- return f'On the moon, you would weigh {earth_weight * 0.166} kilograms.'
+ def surface_area_of_cube(edge_length: float) -> str:
+ return f"The surface area of the cube is {6 * edge_length ** 2}."
-The function ``moon_weight`` takes an argument expected to be an instance of :class:`float`,
-as indicated by the *type hint* ``earth_weight: float``. The function is expected to
-return an instance of :class:`str`, as indicated by the ``-> str`` hint.
+The function ``surface_area_of_cube`` takes an argument expected to
+be an instance of :class:`float`, as indicated by the :term:`type hint`
+``edge_length: float``. The function is expected to return an instance
+of :class:`str`, as indicated by the ``-> str`` hint.
While type hints can be simple classes like :class:`float` or :class:`str`,
they can also be more complex. The :mod:`typing` module provides a vocabulary of
@@ -97,8 +98,9 @@ Type aliases are useful for simplifying complex type signatures. For example::
# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
- message: str,
- servers: Sequence[tuple[tuple[str, int], dict[str, str]]]) -> None:
+ message: str,
+ servers: Sequence[tuple[tuple[str, int], dict[str, str]]]
+ ) -> None:
...
The :keyword:`type` statement is new in Python 3.12. For backwards
@@ -1394,8 +1396,8 @@ These can be used as types in annotations. They all support subscription using
print("Not a list of strings!")
If ``is_str_list`` is a class or instance method, then the type in
- ``TypeGuard`` maps to the type of the second parameter after ``cls`` or
- ``self``.
+ ``TypeGuard`` maps to the type of the second parameter (after ``cls`` or
+ ``self``).
In short, the form ``def foo(arg: TypeA) -> TypeGuard[TypeB]: ...``,
means that if ``foo(arg)`` returns ``True``, then ``arg`` narrows from
@@ -1749,8 +1751,8 @@ without the dedicated syntax, as documented below.
of ``*args``::
def call_soon[*Ts](
- callback: Callable[[*Ts], None],
- *args: *Ts
+ callback: Callable[[*Ts], None],
+ *args: *Ts
) -> None:
...
callback(*args)
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index 8dcb8c2aa547b5..1fbef02a2c69a1 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -856,6 +856,20 @@ object::
3
>>> p.assert_called_once_with()
+.. caution::
+
+ If an :exc:`AttributeError` is raised by :class:`PropertyMock`,
+ it will be interpreted as a missing descriptor and
+ :meth:`~object.__getattr__` will be called on the parent mock::
+
+ >>> m = MagicMock()
+ >>> no_attribute = PropertyMock(side_effect=AttributeError)
+ >>> type(m).my_property = no_attribute
+ >>> m.my_property
+
+
+ See :meth:`~object.__getattr__` for details.
+
.. class:: AsyncMock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs)
diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst
index 68a8ddee0f23f4..b9ba2c21cc8c0c 100644
--- a/Doc/library/unittest.rst
+++ b/Doc/library/unittest.rst
@@ -2308,8 +2308,8 @@ Loading and running tests
(see :ref:`Warning control `),
otherwise it will be set to ``'default'``.
- Calling ``main`` actually returns an instance of the ``TestProgram`` class.
- This stores the result of the tests run as the ``result`` attribute.
+ Calling ``main`` returns an object with the ``result`` attribute that contains
+ the result of the tests run as a :class:`unittest.TestResult`.
.. versionchanged:: 3.1
The *exit* parameter was added.
diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst
index cd402e87a8224b..27909b763e9e43 100644
--- a/Doc/library/urllib.parse.rst
+++ b/Doc/library/urllib.parse.rst
@@ -173,7 +173,7 @@ or on combining URL components into a URL string.
Added IPv6 URL parsing capabilities.
.. versionchanged:: 3.3
- The fragment is now parsed for all URL schemes (unless *allow_fragment* is
+ The fragment is now parsed for all URL schemes (unless *allow_fragments* is
false), in accordance with :rfc:`3986`. Previously, an allowlist of
schemes that support fragments existed.
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index 8705adfb892551..3f00f5018403cd 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -1103,7 +1103,7 @@ FileHandler Objects
.. versionchanged:: 3.2
This method is applicable only for local hostnames. When a remote
- hostname is given, an :exc:`~urllib.error.URLError` is raised.
+ hostname is given, a :exc:`~urllib.error.URLError` is raised.
.. _data-handler-objects:
@@ -1118,7 +1118,7 @@ DataHandler Objects
ignores white spaces in base64 encoded data URLs so the URL may be wrapped
in whatever source file it comes from. But even though some browsers don't
mind about a missing padding at the end of a base64 encoded data URL, this
- implementation will raise an :exc:`ValueError` in that case.
+ implementation will raise a :exc:`ValueError` in that case.
.. _ftp-handler-objects:
diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst
index 2fedd99e8be793..b071ddb554ee38 100644
--- a/Doc/library/xml.etree.elementtree.rst
+++ b/Doc/library/xml.etree.elementtree.rst
@@ -508,7 +508,7 @@ Functions
`C14N 2.0 `_ transformation function.
Canonicalization is a way to normalise XML output in a way that allows
- byte-by-byte comparisons and digital signatures. It reduced the freedom
+ byte-by-byte comparisons and digital signatures. It reduces the freedom
that XML serializers have and instead generates a more constrained XML
representation. The main restrictions regard the placement of namespace
declarations, the ordering of attributes, and ignorable whitespace.
@@ -869,6 +869,7 @@ Element Objects
.. module:: xml.etree.ElementTree
:noindex:
+ :no-index:
.. class:: Element(tag, attrib={}, **extra)
@@ -1053,9 +1054,10 @@ Element Objects
:meth:`~object.__getitem__`, :meth:`~object.__setitem__`,
:meth:`~object.__len__`.
- Caution: Elements with no subelements will test as ``False``. Testing the
- truth value of an Element is deprecated and will raise an exception in
- Python 3.14. Use specific ``len(elem)`` or ``elem is None`` test instead.::
+ Caution: Elements with no subelements will test as ``False``. In a future
+ release of Python, all elements will test as ``True`` regardless of whether
+ subelements exist. Instead, prefer explicit ``len(elem)`` or
+ ``elem is not None`` tests.::
element = root.find('foo')
diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst
index 374404bf33abbe..6d2e948b760978 100644
--- a/Doc/reference/compound_stmts.rst
+++ b/Doc/reference/compound_stmts.rst
@@ -245,13 +245,12 @@ handler is started. This search inspects the :keyword:`!except` clauses in turn
until one is found that matches the exception.
An expression-less :keyword:`!except` clause, if present, must be last;
it matches any exception.
-For an :keyword:`!except` clause with an expression,
-that expression is evaluated, and the clause matches the exception
-if the resulting object is "compatible" with the exception. An object is
-compatible with an exception if the object is the class or a
-:term:`non-virtual base class ` of the exception object,
-or a tuple containing an item that is the class or a non-virtual base class
-of the exception object.
+
+For an :keyword:`!except` clause with an expression, the
+expression must evaluate to an exception type or a tuple of exception types.
+The raised exception matches an :keyword:`!except` clause whose expression evaluates
+to the class or a :term:`non-virtual base class ` of the exception object,
+or to a tuple that contains such a class.
If no :keyword:`!except` clause matches the exception,
the search for an exception handler
@@ -378,8 +377,10 @@ exception group with an empty message string. ::
...
ExceptionGroup('', (BlockingIOError()))
-An :keyword:`!except*` clause must have a matching type,
-and this type cannot be a subclass of :exc:`BaseExceptionGroup`.
+An :keyword:`!except*` clause must have a matching expression; it cannot be ``except*:``.
+Furthermore, this expression cannot contain exception group types, because that would
+have ambiguous semantics.
+
It is not possible to mix :keyword:`except` and :keyword:`!except*`
in the same :keyword:`try`.
:keyword:`break`, :keyword:`continue` and :keyword:`return`
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 602014deebaa7b..25ca94fd5a8d47 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -215,7 +215,7 @@ properties:
* A sign is shown only when the number is negative.
-Python distinguishes between integers, floating point numbers, and complex
+Python distinguishes between integers, floating-point numbers, and complex
numbers:
@@ -259,18 +259,18 @@ Booleans (:class:`bool`)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index::
- pair: object; floating point
- pair: floating point; number
+ pair: object; floating-point
+ pair: floating-point; number
pair: C; language
pair: Java; language
-These represent machine-level double precision floating point numbers. You are
+These represent machine-level double precision floating-point numbers. You are
at the mercy of the underlying machine architecture (and C or Java
implementation) for the accepted range and handling of overflow. Python does not
-support single-precision floating point numbers; the savings in processor and
+support single-precision floating-point numbers; the savings in processor and
memory usage that are usually the reason for using these are dwarfed by the
overhead of using objects in Python, so there is no reason to complicate the
-language with two kinds of floating point numbers.
+language with two kinds of floating-point numbers.
:class:`numbers.Complex` (:class:`complex`)
@@ -281,7 +281,7 @@ language with two kinds of floating point numbers.
pair: complex; number
These represent complex numbers as a pair of machine-level double precision
-floating point numbers. The same caveats apply as for floating point numbers.
+floating-point numbers. The same caveats apply as for floating-point numbers.
The real and imaginary parts of a complex number ``z`` can be retrieved through
the read-only attributes ``z.real`` and ``z.imag``.
@@ -727,14 +727,7 @@ When an instance method object is derived from a :class:`classmethod` object, th
itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to
calling ``f(C,1)`` where ``f`` is the underlying function.
-Note that the transformation from :ref:`function object `
-to instance method
-object happens each time the attribute is retrieved from the instance. In
-some cases, a fruitful optimization is to assign the attribute to a local
-variable and call that local variable. Also notice that this
-transformation only happens for user-defined functions; other callable
-objects (and all non-callable objects) are retrieved without
-transformation. It is also important to note that user-defined functions
+It is important to note that user-defined functions
which are attributes of a class instance are not converted to bound
methods; this *only* happens when the function is an attribute of the
class.
@@ -1643,6 +1636,8 @@ Basic customization
It is not guaranteed that :meth:`__del__` methods are called for objects
that still exist when the interpreter exits.
+ :class:`weakref.finalize` provides a straightforward way to register
+ a cleanup function to be called when an object is garbage collected.
.. note::
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 38f00ae2aa03c9..77127bda474e8d 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -33,7 +33,7 @@ implementation for built-in types works as follows:
* If either argument is a complex number, the other is converted to complex;
-* otherwise, if either argument is a floating point number, the other is
+* otherwise, if either argument is a floating-point number, the other is
converted to floating point;
* otherwise, both must be integers and no conversion is necessary.
@@ -83,18 +83,47 @@ exception.
pair: name; mangling
pair: private; names
-**Private name mangling:** When an identifier that textually occurs in a class
-definition begins with two or more underscore characters and does not end in two
-or more underscores, it is considered a :dfn:`private name` of that class.
-Private names are transformed to a longer form before code is generated for
-them. The transformation inserts the class name, with leading underscores
-removed and a single underscore inserted, in front of the name. For example,
-the identifier ``__spam`` occurring in a class named ``Ham`` will be transformed
-to ``_Ham__spam``. This transformation is independent of the syntactical
-context in which the identifier is used. If the transformed name is extremely
-long (longer than 255 characters), implementation defined truncation may happen.
-If the class name consists only of underscores, no transformation is done.
+Private name mangling
+^^^^^^^^^^^^^^^^^^^^^
+When an identifier that textually occurs in a class definition begins with two
+or more underscore characters and does not end in two or more underscores, it
+is considered a :dfn:`private name` of that class.
+
+.. seealso::
+
+ The :ref:`class specifications `.
+
+More precisely, private names are transformed to a longer form before code is
+generated for them. If the transformed name is longer than 255 characters,
+implementation-defined truncation may happen.
+
+The transformation is independent of the syntactical context in which the
+identifier is used but only the following private identifiers are mangled:
+
+- Any name used as the name of a variable that is assigned or read or any
+ name of an attribute being accessed.
+
+ The ``__name__`` attribute of nested functions, classes, and type aliases
+ is however not mangled.
+
+- The name of imported modules, e.g., ``__spam`` in ``import __spam``.
+ If the module is part of a package (i.e., its name contains a dot),
+ the name is *not* mangled, e.g., the ``__foo`` in ``import __foo.bar``
+ is not mangled.
+
+- The name of an imported member, e.g., ``__f`` in ``from spam import __f``.
+
+The transformation rule is defined as follows:
+
+- The class name, with leading underscores removed and a single leading
+ underscore inserted, is inserted in front of the identifier, e.g., the
+ identifier ``__spam`` occurring in a class named ``Foo``, ``_Foo`` or
+ ``__Foo`` is transformed to ``_Foo__spam``.
+
+- If the class name consists only of underscores, the transformation is the
+ identity, e.g., the identifier ``__spam`` occurring in a class named ``_``
+ or ``__`` is left as is.
.. _atom-literals:
@@ -110,8 +139,8 @@ Python supports string and bytes literals and various numeric literals:
: | `integer` | `floatnumber` | `imagnumber`
Evaluation of a literal yields an object of the given type (string, bytes,
-integer, floating point number, complex number) with the given value. The value
-may be approximated in the case of floating point and imaginary (complex)
+integer, floating-point number, complex number) with the given value. The value
+may be approximated in the case of floating-point and imaginary (complex)
literals. See section :ref:`literals` for details.
.. index::
@@ -218,10 +247,12 @@ A comprehension in an :keyword:`!async def` function may consist of either a
:keyword:`!for` or :keyword:`!async for` clause following the leading
expression, may contain additional :keyword:`!for` or :keyword:`!async for`
clauses, and may also use :keyword:`await` expressions.
-If a comprehension contains either :keyword:`!async for` clauses or
-:keyword:`!await` expressions or other asynchronous comprehensions it is called
-an :dfn:`asynchronous comprehension`. An asynchronous comprehension may
-suspend the execution of the coroutine function in which it appears.
+
+If a comprehension contains :keyword:`!async for` clauses, or if it contains
+:keyword:`!await` expressions or other asynchronous comprehensions anywhere except
+the iterable expression in the leftmost :keyword:`!for` clause, it is called an
+:dfn:`asynchronous comprehension`. An asynchronous comprehension may suspend the
+execution of the coroutine function in which it appears.
See also :pep:`530`.
.. versionadded:: 3.6
@@ -1204,7 +1235,8 @@ Raising ``0.0`` to a negative power results in a :exc:`ZeroDivisionError`.
Raising a negative number to a fractional power results in a :class:`complex`
number. (In earlier versions it raised a :exc:`ValueError`.)
-This operation can be customized using the special :meth:`~object.__pow__` method.
+This operation can be customized using the special :meth:`~object.__pow__` and
+:meth:`~object.__rpow__` methods.
.. _unary:
@@ -1292,6 +1324,9 @@ This operation can be customized using the special :meth:`~object.__mul__` and
The ``@`` (at) operator is intended to be used for matrix multiplication. No
builtin Python types implement this operator.
+This operation can be customized using the special :meth:`~object.__matmul__` and
+:meth:`~object.__rmatmul__` methods.
+
.. versionadded:: 3.5
.. index::
@@ -1307,8 +1342,10 @@ integer; the result is that of mathematical division with the 'floor' function
applied to the result. Division by zero raises the :exc:`ZeroDivisionError`
exception.
-This operation can be customized using the special :meth:`~object.__truediv__` and
-:meth:`~object.__floordiv__` methods.
+The division operation can be customized using the special :meth:`~object.__truediv__`
+and :meth:`~object.__rtruediv__` methods.
+The floor division operation can be customized using the special
+:meth:`~object.__floordiv__` and :meth:`~object.__rfloordiv__` methods.
.. index::
single: modulo
@@ -1317,7 +1354,7 @@ This operation can be customized using the special :meth:`~object.__truediv__` a
The ``%`` (modulo) operator yields the remainder from the division of the first
argument by the second. The numeric arguments are first converted to a common
type. A zero right argument raises the :exc:`ZeroDivisionError` exception. The
-arguments may be floating point numbers, e.g., ``3.14%0.7`` equals ``0.34``
+arguments may be floating-point numbers, e.g., ``3.14%0.7`` equals ``0.34``
(since ``3.14`` equals ``4*0.7 + 0.34``.) The modulo operator always yields a
result with the same sign as its second operand (or zero); the absolute value of
the result is strictly smaller than the absolute value of the second operand
@@ -1333,11 +1370,12 @@ also overloaded by string objects to perform old-style string formatting (also
known as interpolation). The syntax for string formatting is described in the
Python Library Reference, section :ref:`old-string-formatting`.
-The *modulo* operation can be customized using the special :meth:`~object.__mod__` method.
+The *modulo* operation can be customized using the special :meth:`~object.__mod__`
+and :meth:`~object.__rmod__` methods.
The floor division operator, the modulo operator, and the :func:`divmod`
-function are not defined for complex numbers. Instead, convert to a floating
-point number using the :func:`abs` function if appropriate.
+function are not defined for complex numbers. Instead, convert to a
+floating-point number using the :func:`abs` function if appropriate.
.. index::
single: addition
@@ -1360,7 +1398,8 @@ This operation can be customized using the special :meth:`~object.__add__` and
The ``-`` (subtraction) operator yields the difference of its arguments. The
numeric arguments are first converted to a common type.
-This operation can be customized using the special :meth:`~object.__sub__` method.
+This operation can be customized using the special :meth:`~object.__sub__` and
+:meth:`~object.__rsub__` methods.
.. _shifting:
@@ -1381,8 +1420,10 @@ The shifting operations have lower priority than the arithmetic operations:
These operators accept integers as arguments. They shift the first argument to
the left or right by the number of bits given by the second argument.
-This operation can be customized using the special :meth:`~object.__lshift__` and
-:meth:`~object.__rshift__` methods.
+The left shift operation can be customized using the special :meth:`~object.__lshift__`
+and :meth:`~object.__rlshift__` methods.
+The right shift operation can be customized using the special :meth:`~object.__rshift__`
+and :meth:`~object.__rrshift__` methods.
.. index:: pair: exception; ValueError
diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst
index 103d6ef05e4bb8..e9b1c2733aaaa4 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -879,10 +879,10 @@ Numeric literals
----------------
.. index:: number, numeric literal, integer literal
- floating point literal, hexadecimal literal
+ floating-point literal, hexadecimal literal
octal literal, binary literal, decimal literal, imaginary literal, complex literal
-There are three types of numeric literals: integers, floating point numbers, and
+There are three types of numeric literals: integers, floating-point numbers, and
imaginary numbers. There are no complex literals (complex numbers can be formed
by adding a real number and an imaginary number).
@@ -943,10 +943,10 @@ Some examples of integer literals::
single: _ (underscore); in numeric literal
.. _floating:
-Floating point literals
+Floating-point literals
-----------------------
-Floating point literals are described by the following lexical definitions:
+Floating-point literals are described by the following lexical definitions:
.. productionlist:: python-grammar
floatnumber: `pointfloat` | `exponentfloat`
@@ -958,10 +958,10 @@ Floating point literals are described by the following lexical definitions:
Note that the integer and exponent parts are always interpreted using radix 10.
For example, ``077e010`` is legal, and denotes the same number as ``77e10``. The
-allowed range of floating point literals is implementation-dependent. As in
+allowed range of floating-point literals is implementation-dependent. As in
integer literals, underscores are supported for digit grouping.
-Some examples of floating point literals::
+Some examples of floating-point literals::
3.14 10. .001 1e100 3.14e-10 0e0 3.14_15_93
@@ -982,9 +982,9 @@ Imaginary literals are described by the following lexical definitions:
imagnumber: (`floatnumber` | `digitpart`) ("j" | "J")
An imaginary literal yields a complex number with a real part of 0.0. Complex
-numbers are represented as a pair of floating point numbers and have the same
+numbers are represented as a pair of floating-point numbers and have the same
restrictions on their range. To create a complex number with a nonzero real
-part, add a floating point number to it, e.g., ``(3+4j)``. Some examples of
+part, add a floating-point number to it, e.g., ``(3+4j)``. Some examples of
imaginary literals::
3.14j 10.j 10j .001j 1e100j 3.14e-10j 3.14_15_93j
diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst
index a253482156d3b4..618664b23f0680 100644
--- a/Doc/reference/simple_stmts.rst
+++ b/Doc/reference/simple_stmts.rst
@@ -293,7 +293,7 @@ statements, cannot be an unpacking) and the expression list, performs the binary
operation specific to the type of assignment on the two operands, and assigns
the result to the original target. The target is only evaluated once.
-An augmented assignment expression like ``x += 1`` can be rewritten as ``x = x +
+An augmented assignment statement like ``x += 1`` can be rewritten as ``x = x +
1`` to achieve a similar, but not exactly equal effect. In the augmented
version, ``x`` is only evaluated once. Also, when possible, the actual operation
is performed *in-place*, meaning that rather than creating a new object and
@@ -333,7 +333,9 @@ statement, of a variable or attribute annotation and an optional assignment stat
The difference from normal :ref:`assignment` is that only a single target is allowed.
-For simple names as assignment targets, if in class or module scope,
+The assignment target is considered "simple" if it consists of a single
+name that is not enclosed in parentheses.
+For simple assignment targets, if in class or module scope,
the annotations are evaluated and stored in a special class or module
attribute :attr:`__annotations__`
that is a dictionary mapping from variable names (mangled if private) to
@@ -341,7 +343,8 @@ evaluated annotations. This attribute is writable and is automatically
created at the start of class or module body execution, if annotations
are found statically.
-For expressions as assignment targets, the annotations are evaluated if
+If the assignment target is not simple (an attribute, subscript node, or
+parenthesized name), the annotation is evaluated if
in class or module scope, but not stored.
If a name is annotated in a function scope, then this name is local for
diff --git a/Doc/requirements-oldest-sphinx.txt b/Doc/requirements-oldest-sphinx.txt
index 3ae65bc944da26..068fe0cb426ecd 100644
--- a/Doc/requirements-oldest-sphinx.txt
+++ b/Doc/requirements-oldest-sphinx.txt
@@ -14,16 +14,16 @@ python-docs-theme>=2022.1
alabaster==0.7.16
Babel==2.15.0
-certifi==2024.2.2
+certifi==2024.7.4
charset-normalizer==3.3.2
docutils==0.19
idna==3.7
imagesize==1.4.1
Jinja2==3.1.4
MarkupSafe==2.1.5
-packaging==24.0
+packaging==24.1
Pygments==2.18.0
-requests==2.32.2
+requests==2.32.3
snowballstemmer==2.2.0
Sphinx==6.2.1
sphinxcontrib-applehelp==1.0.8
@@ -32,4 +32,4 @@ sphinxcontrib-htmlhelp==2.0.5
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.7
sphinxcontrib-serializinghtml==1.1.10
-urllib3==2.2.1
+urllib3==2.2.2
diff --git a/Doc/requirements.txt b/Doc/requirements.txt
index b47a9d8a8635ab..bf1028020b7af7 100644
--- a/Doc/requirements.txt
+++ b/Doc/requirements.txt
@@ -6,12 +6,12 @@
# Sphinx version is pinned so that new versions that introduce new warnings
# won't suddenly cause build failures. Updating the version is fine as long
# as no warnings are raised by doing so.
-sphinx~=7.3.0
+sphinx~=8.0.0
blurb
-sphinxext-opengraph==0.7.5
-sphinx-notfound-page==1.0.0
+sphinxext-opengraph~=0.9.0
+sphinx-notfound-page~=1.0.0
# The theme used by the documentation is stored separately, so we need
# to install that as well.
diff --git a/Doc/tools/check-warnings.py b/Doc/tools/check-warnings.py
index c50b00636c36ce..8f92ab298ebb1d 100644
--- a/Doc/tools/check-warnings.py
+++ b/Doc/tools/check-warnings.py
@@ -2,6 +2,7 @@
"""
Check the output of running Sphinx in nit-picky mode (missing references).
"""
+
from __future__ import annotations
import argparse
@@ -14,7 +15,7 @@
from typing import TextIO
# Fail if NEWS nit found before this line number
-NEWS_NIT_THRESHOLD = 200
+NEWS_NIT_THRESHOLD = 300
# Exclude these whether they're dirty or clean,
# because they trigger a rebuild of dirty files.
@@ -206,7 +207,9 @@ def annotate_diff(
def fail_if_regression(
- warnings: list[str], files_with_expected_nits: set[str], files_with_nits: set[str]
+ warnings: list[str],
+ files_with_expected_nits: set[str],
+ files_with_nits: set[str],
) -> int:
"""
Ensure some files always pass Sphinx nit-picky mode (no missing references).
@@ -252,17 +255,11 @@ def fail_if_new_news_nit(warnings: list[str], threshold: int) -> int:
"""
Ensure no warnings are found in the NEWS file before a given line number.
"""
- news_nits = (
- warning
- for warning in warnings
- if "/build/NEWS:" in warning
- )
+ news_nits = (warning for warning in warnings if "/build/NEWS:" in warning)
# Nits found before the threshold line
new_news_nits = [
- nit
- for nit in news_nits
- if int(nit.split(":")[1]) <= threshold
+ nit for nit in news_nits if int(nit.split(":")[1]) <= threshold
]
if new_news_nits:
@@ -311,7 +308,8 @@ def main(argv: list[str] | None = None) -> int:
exit_code = 0
wrong_directory_msg = "Must run this script from the repo root"
- assert Path("Doc").exists() and Path("Doc").is_dir(), wrong_directory_msg
+ if not Path("Doc").exists() or not Path("Doc").is_dir():
+ raise RuntimeError(wrong_directory_msg)
with Path("Doc/sphinx-warnings.txt").open(encoding="UTF-8") as f:
warnings = f.read().splitlines()
@@ -339,7 +337,9 @@ def main(argv: list[str] | None = None) -> int:
)
if args.fail_if_improved:
- exit_code += fail_if_improved(files_with_expected_nits, files_with_nits)
+ exit_code += fail_if_improved(
+ files_with_expected_nits, files_with_nits
+ )
if args.fail_if_new_news_nit:
exit_code += fail_if_new_news_nit(warnings, args.fail_if_new_news_nit)
diff --git a/Doc/tools/extensions/audit_events.py b/Doc/tools/extensions/audit_events.py
new file mode 100644
index 00000000000000..23d82c0f4414bf
--- /dev/null
+++ b/Doc/tools/extensions/audit_events.py
@@ -0,0 +1,264 @@
+"""Support for documenting audit events."""
+
+from __future__ import annotations
+
+import re
+from typing import TYPE_CHECKING
+
+from docutils import nodes
+from sphinx.errors import NoUri
+from sphinx.locale import _ as sphinx_gettext
+from sphinx.transforms.post_transforms import SphinxPostTransform
+from sphinx.util import logging
+from sphinx.util.docutils import SphinxDirective
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+
+ from sphinx.application import Sphinx
+ from sphinx.builders import Builder
+ from sphinx.environment import BuildEnvironment
+
+logger = logging.getLogger(__name__)
+
+# This list of sets are allowable synonyms for event argument names.
+# If two names are in the same set, they are treated as equal for the
+# purposes of warning. This won't help if the number of arguments is
+# different!
+_SYNONYMS = [
+ frozenset({"file", "path", "fd"}),
+]
+
+
+class AuditEvents:
+ def __init__(self) -> None:
+ self.events: dict[str, list[str]] = {}
+ self.sources: dict[str, list[tuple[str, str]]] = {}
+
+ def __iter__(self) -> Iterator[tuple[str, list[str], tuple[str, str]]]:
+ for name, args in self.events.items():
+ for source in self.sources[name]:
+ yield name, args, source
+
+ def add_event(
+ self, name, args: list[str], source: tuple[str, str]
+ ) -> None:
+ if name in self.events:
+ self._check_args_match(name, args)
+ else:
+ self.events[name] = args
+ self.sources.setdefault(name, []).append(source)
+
+ def _check_args_match(self, name: str, args: list[str]) -> None:
+ current_args = self.events[name]
+ msg = (
+ f"Mismatched arguments for audit-event {name}: "
+ f"{current_args!r} != {args!r}"
+ )
+ if current_args == args:
+ return
+ if len(current_args) != len(args):
+ logger.warning(msg)
+ return
+ for a1, a2 in zip(current_args, args, strict=False):
+ if a1 == a2:
+ continue
+ if any(a1 in s and a2 in s for s in _SYNONYMS):
+ continue
+ logger.warning(msg)
+ return
+
+ def id_for(self, name) -> str:
+ source_count = len(self.sources.get(name, ()))
+ name_clean = re.sub(r"\W", "_", name)
+ return f"audit_event_{name_clean}_{source_count}"
+
+ def rows(self) -> Iterator[tuple[str, list[str], list[tuple[str, str]]]]:
+ for name in sorted(self.events.keys()):
+ yield name, self.events[name], self.sources[name]
+
+
+def initialise_audit_events(app: Sphinx) -> None:
+ """Initialise the audit_events attribute on the environment."""
+ if not hasattr(app.env, "audit_events"):
+ app.env.audit_events = AuditEvents()
+
+
+def audit_events_purge(
+ app: Sphinx, env: BuildEnvironment, docname: str
+) -> None:
+ """This is to remove traces of removed documents from env.audit_events."""
+ fresh_audit_events = AuditEvents()
+ for name, args, (doc, target) in env.audit_events:
+ if doc != docname:
+ fresh_audit_events.add_event(name, args, (doc, target))
+
+
+def audit_events_merge(
+ app: Sphinx,
+ env: BuildEnvironment,
+ docnames: list[str],
+ other: BuildEnvironment,
+) -> None:
+ """In Sphinx parallel builds, this merges audit_events from subprocesses."""
+ for name, args, source in other.audit_events:
+ env.audit_events.add_event(name, args, source)
+
+
+class AuditEvent(SphinxDirective):
+ has_content = True
+ required_arguments = 1
+ optional_arguments = 2
+ final_argument_whitespace = True
+
+ _label = [
+ sphinx_gettext(
+ "Raises an :ref:`auditing event ` "
+ "{name} with no arguments."
+ ),
+ sphinx_gettext(
+ "Raises an :ref:`auditing event ` "
+ "{name} with argument {args}."
+ ),
+ sphinx_gettext(
+ "Raises an :ref:`auditing event ` "
+ "{name} with arguments {args}."
+ ),
+ ]
+
+ def run(self) -> list[nodes.paragraph]:
+ name = self.arguments[0]
+ if len(self.arguments) >= 2 and self.arguments[1]:
+ args = [
+ arg
+ for argument in self.arguments[1].strip("'\"").split(",")
+ if (arg := argument.strip())
+ ]
+ else:
+ args = []
+ ids = []
+ try:
+ target = self.arguments[2].strip("\"'")
+ except (IndexError, TypeError):
+ target = None
+ if not target:
+ target = self.env.audit_events.id_for(name)
+ ids.append(target)
+ self.env.audit_events.add_event(name, args, (self.env.docname, target))
+
+ node = nodes.paragraph("", classes=["audit-hook"], ids=ids)
+ self.set_source_info(node)
+ if self.content:
+ node.rawsource = '\n'.join(self.content) # for gettext
+ self.state.nested_parse(self.content, self.content_offset, node)
+ else:
+ num_args = min(2, len(args))
+ text = self._label[num_args].format(
+ name=f"``{name}``",
+ args=", ".join(f"``{a}``" for a in args),
+ )
+ node.rawsource = text # for gettext
+ parsed, messages = self.state.inline_text(text, self.lineno)
+ node += parsed
+ node += messages
+ return [node]
+
+
+class audit_event_list(nodes.General, nodes.Element): # noqa: N801
+ pass
+
+
+class AuditEventListDirective(SphinxDirective):
+ def run(self) -> list[audit_event_list]:
+ return [audit_event_list()]
+
+
+class AuditEventListTransform(SphinxPostTransform):
+ default_priority = 500
+
+ def run(self) -> None:
+ if self.document.next_node(audit_event_list) is None:
+ return
+
+ table = self._make_table(self.app.builder, self.env.docname)
+ for node in self.document.findall(audit_event_list):
+ node.replace_self(table)
+
+ def _make_table(self, builder: Builder, docname: str) -> nodes.table:
+ table = nodes.table(cols=3)
+ group = nodes.tgroup(
+ "",
+ nodes.colspec(colwidth=30),
+ nodes.colspec(colwidth=55),
+ nodes.colspec(colwidth=15),
+ cols=3,
+ )
+ head = nodes.thead()
+ body = nodes.tbody()
+
+ table += group
+ group += head
+ group += body
+
+ head += nodes.row(
+ "",
+ nodes.entry("", nodes.paragraph("", "Audit event")),
+ nodes.entry("", nodes.paragraph("", "Arguments")),
+ nodes.entry("", nodes.paragraph("", "References")),
+ )
+
+ for name, args, sources in builder.env.audit_events.rows():
+ body += self._make_row(builder, docname, name, args, sources)
+
+ return table
+
+ @staticmethod
+ def _make_row(
+ builder: Builder,
+ docname: str,
+ name: str,
+ args: list[str],
+ sources: list[tuple[str, str]],
+ ) -> nodes.row:
+ row = nodes.row()
+ name_node = nodes.paragraph("", nodes.Text(name))
+ row += nodes.entry("", name_node)
+
+ args_node = nodes.paragraph()
+ for arg in args:
+ args_node += nodes.literal(arg, arg)
+ args_node += nodes.Text(", ")
+ if len(args_node.children) > 0:
+ args_node.children.pop() # remove trailing comma
+ row += nodes.entry("", args_node)
+
+ backlinks_node = nodes.paragraph()
+ backlinks = enumerate(sorted(set(sources)), start=1)
+ for i, (doc, label) in backlinks:
+ if isinstance(label, str):
+ ref = nodes.reference("", f"[{i}]", internal=True)
+ try:
+ target = (
+ f"{builder.get_relative_uri(docname, doc)}#{label}"
+ )
+ except NoUri:
+ continue
+ else:
+ ref["refuri"] = target
+ backlinks_node += ref
+ row += nodes.entry("", backlinks_node)
+ return row
+
+
+def setup(app: Sphinx):
+ app.add_directive("audit-event", AuditEvent)
+ app.add_directive("audit-event-table", AuditEventListDirective)
+ app.add_post_transform(AuditEventListTransform)
+ app.connect("builder-inited", initialise_audit_events)
+ app.connect("env-purge-doc", audit_events_purge)
+ app.connect("env-merge-info", audit_events_merge)
+ return {
+ "version": "1.0",
+ "parallel_read_safe": True,
+ "parallel_write_safe": True,
+ }
diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py
index 7916b178f1c0f1..a65cf71e4affe3 100644
--- a/Doc/tools/extensions/c_annotations.py
+++ b/Doc/tools/extensions/c_annotations.py
@@ -1,226 +1,305 @@
-"""
- c_annotations.py
- ~~~~~~~~~~~~~~~~
-
- Supports annotations for C API elements:
+"""Support annotations for C API elements.
- * reference count annotations for C API functions. Based on
- refcount.py and anno-api.py in the old Python documentation tools.
+* Reference count annotations for C API functions.
+* Stable ABI annotations
+* Limited API annotations
- * stable API annotations
+Configuration:
+* Set ``refcount_file`` to the path to the reference count data file.
+* Set ``stable_abi_file`` to the path to stable ABI list.
+"""
- Usage:
- * Set the `refcount_file` config value to the path to the reference
- count data file.
- * Set the `stable_abi_file` config value to the path to stable ABI list.
+from __future__ import annotations
- :copyright: Copyright 2007-2014 by Georg Brandl.
- :license: Python license.
-"""
+import csv
+import dataclasses
+from pathlib import Path
+from typing import TYPE_CHECKING
-from os import path
+import sphinx
from docutils import nodes
-from docutils.parsers.rst import directives
-from docutils.parsers.rst import Directive
from docutils.statemachine import StringList
-from sphinx.locale import _ as sphinx_gettext
-import csv
-
from sphinx import addnodes
-from sphinx.domains.c import CObject
+from sphinx.locale import _ as sphinx_gettext
+from sphinx.util.docutils import SphinxDirective
+if TYPE_CHECKING:
+ from sphinx.application import Sphinx
+ from sphinx.util.typing import ExtensionMetadata
-REST_ROLE_MAP = {
- 'function': 'func',
- 'macro': 'macro',
- 'member': 'member',
- 'type': 'type',
- 'var': 'data',
+ROLE_TO_OBJECT_TYPE = {
+ "func": "function",
+ "macro": "macro",
+ "member": "member",
+ "type": "type",
+ "data": "var",
}
-class RCEntry:
- def __init__(self, name):
- self.name = name
- self.args = []
- self.result_type = ''
- self.result_refs = None
-
-
-class Annotations:
- def __init__(self, refcount_filename, stable_abi_file):
- self.refcount_data = {}
- with open(refcount_filename, encoding='utf8') as fp:
- for line in fp:
- line = line.strip()
- if line[:1] in ("", "#"):
- # blank lines and comments
- continue
- parts = line.split(":", 4)
- if len(parts) != 5:
- raise ValueError(f"Wrong field count in {line!r}")
- function, type, arg, refcount, comment = parts
- # Get the entry, creating it if needed:
- try:
- entry = self.refcount_data[function]
- except KeyError:
- entry = self.refcount_data[function] = RCEntry(function)
- if not refcount or refcount == "null":
- refcount = None
- else:
- refcount = int(refcount)
- # Update the entry with the new parameter or the result
- # information.
- if arg:
- entry.args.append((arg, type, refcount))
- else:
- entry.result_type = type
- entry.result_refs = refcount
-
- self.stable_abi_data = {}
- with open(stable_abi_file, encoding='utf8') as fp:
- for record in csv.DictReader(fp):
- name = record['name']
- self.stable_abi_data[name] = record
-
- def add_annotations(self, app, doctree):
- for node in doctree.findall(addnodes.desc_content):
- par = node.parent
- if par['domain'] != 'c':
- continue
- if not par[0].has_key('ids') or not par[0]['ids']:
- continue
- name = par[0]['ids'][0]
- if name.startswith("c."):
- name = name[2:]
-
- objtype = par['objtype']
-
- # Stable ABI annotation. These have two forms:
- # Part of the [Stable ABI](link).
- # Part of the [Stable ABI](link) since version X.Y.
- # For structs, there's some more info in the message:
- # Part of the [Limited API](link) (as an opaque struct).
- # Part of the [Stable ABI](link) (including all members).
- # Part of the [Limited API](link) (Only some members are part
- # of the stable ABI.).
- # ... all of which can have "since version X.Y" appended.
- record = self.stable_abi_data.get(name)
- if record:
- if record['role'] != objtype:
- raise ValueError(
- f"Object type mismatch in limited API annotation "
- f"for {name}: {record['role']!r} != {objtype!r}")
- stable_added = record['added']
- message = sphinx_gettext('Part of the')
- message = message.center(len(message) + 2)
- emph_node = nodes.emphasis(message, message,
- classes=['stableabi'])
- ref_node = addnodes.pending_xref(
- 'Stable ABI', refdomain="std", reftarget='stable',
- reftype='ref', refexplicit="False")
- struct_abi_kind = record['struct_abi_kind']
- if struct_abi_kind in {'opaque', 'members'}:
- ref_node += nodes.Text(sphinx_gettext('Limited API'))
- else:
- ref_node += nodes.Text(sphinx_gettext('Stable ABI'))
- emph_node += ref_node
- if struct_abi_kind == 'opaque':
- emph_node += nodes.Text(' ' + sphinx_gettext('(as an opaque struct)'))
- elif struct_abi_kind == 'full-abi':
- emph_node += nodes.Text(' ' + sphinx_gettext('(including all members)'))
- if record['ifdef_note']:
- emph_node += nodes.Text(' ' + record['ifdef_note'])
- if stable_added == '3.2':
- # Stable ABI was introduced in 3.2.
- pass
- else:
- emph_node += nodes.Text(' ' + sphinx_gettext('since version %s') % stable_added)
- emph_node += nodes.Text('.')
- if struct_abi_kind == 'members':
- emph_node += nodes.Text(
- ' ' + sphinx_gettext('(Only some members are part of the stable ABI.)'))
- node.insert(0, emph_node)
-
- # Unstable API annotation.
- if name.startswith('PyUnstable'):
- warn_node = nodes.admonition(
- classes=['unstable-c-api', 'warning'])
- message = sphinx_gettext('This is') + ' '
- emph_node = nodes.emphasis(message, message)
- ref_node = addnodes.pending_xref(
- 'Unstable API', refdomain="std",
- reftarget='unstable-c-api',
- reftype='ref', refexplicit="False")
- ref_node += nodes.Text(sphinx_gettext('Unstable API'))
- emph_node += ref_node
- emph_node += nodes.Text(sphinx_gettext('. It may change without warning in minor releases.'))
- warn_node += emph_node
- node.insert(0, warn_node)
-
- # Return value annotation
- if objtype != 'function':
- continue
- entry = self.refcount_data.get(name)
- if not entry:
- continue
- elif not entry.result_type.endswith("Object*"):
- continue
- classes = ['refcount']
- if entry.result_refs is None:
- rc = sphinx_gettext('Return value: Always NULL.')
- classes.append('return_null')
- elif entry.result_refs:
- rc = sphinx_gettext('Return value: New reference.')
- classes.append('return_new_ref')
- else:
- rc = sphinx_gettext('Return value: Borrowed reference.')
- classes.append('return_borrowed_ref')
- node.insert(0, nodes.emphasis(rc, rc, classes=classes))
-
-
-def init_annotations(app):
- annotations = Annotations(
- path.join(app.srcdir, app.config.refcount_file),
- path.join(app.srcdir, app.config.stable_abi_file),
+@dataclasses.dataclass(slots=True)
+class RefCountEntry:
+ # Name of the function.
+ name: str
+ # List of (argument name, type, refcount effect) tuples.
+ # (Currently not used. If it was, a dataclass might work better.)
+ args: list = dataclasses.field(default_factory=list)
+ # Return type of the function.
+ result_type: str = ""
+ # Reference count effect for the return value.
+ result_refs: int | None = None
+
+
+@dataclasses.dataclass(frozen=True, slots=True)
+class StableABIEntry:
+ # Role of the object.
+ # Source: Each [item_kind] in stable_abi.toml is mapped to a C Domain role.
+ role: str
+ # Name of the object.
+ # Source: [.*] in stable_abi.toml.
+ name: str
+ # Version when the object was added to the stable ABI.
+ # (Source: [.*.added] in stable_abi.toml.
+ added: str
+ # An explananatory blurb for the ifdef.
+ # Source: ``feature_macro.*.doc`` in stable_abi.toml.
+ ifdef_note: str
+ # Defines how much of the struct is exposed. Only relevant for structs.
+ # Source: [.*.struct_abi_kind] in stable_abi.toml.
+ struct_abi_kind: str
+
+
+def read_refcount_data(refcount_filename: Path) -> dict[str, RefCountEntry]:
+ refcount_data = {}
+ refcounts = refcount_filename.read_text(encoding="utf8")
+ for line in refcounts.splitlines():
+ line = line.strip()
+ if not line or line.startswith("#"):
+ # blank lines and comments
+ continue
+
+ # Each line is of the form
+ # function ':' type ':' [param name] ':' [refcount effect] ':' [comment]
+ parts = line.split(":", 4)
+ if len(parts) != 5:
+ raise ValueError(f"Wrong field count in {line!r}")
+ function, type, arg, refcount, _comment = parts
+
+ # Get the entry, creating it if needed:
+ try:
+ entry = refcount_data[function]
+ except KeyError:
+ entry = refcount_data[function] = RefCountEntry(function)
+ if not refcount or refcount == "null":
+ refcount = None
+ else:
+ refcount = int(refcount)
+ # Update the entry with the new parameter
+ # or the result information.
+ if arg:
+ entry.args.append((arg, type, refcount))
+ else:
+ entry.result_type = type
+ entry.result_refs = refcount
+
+ return refcount_data
+
+
+def read_stable_abi_data(stable_abi_file: Path) -> dict[str, StableABIEntry]:
+ stable_abi_data = {}
+ with open(stable_abi_file, encoding="utf8") as fp:
+ for record in csv.DictReader(fp):
+ name = record["name"]
+ stable_abi_data[name] = StableABIEntry(**record)
+
+ return stable_abi_data
+
+
+def add_annotations(app: Sphinx, doctree: nodes.document) -> None:
+ state = app.env.domaindata["c_annotations"]
+ refcount_data = state["refcount_data"]
+ stable_abi_data = state["stable_abi_data"]
+ for node in doctree.findall(addnodes.desc_content):
+ par = node.parent
+ if par["domain"] != "c":
+ continue
+ if not par[0].get("ids", None):
+ continue
+ name = par[0]["ids"][0]
+ if name.startswith("c."):
+ name = name[2:]
+
+ objtype = par["objtype"]
+
+ # Stable ABI annotation.
+ if record := stable_abi_data.get(name):
+ if ROLE_TO_OBJECT_TYPE[record.role] != objtype:
+ msg = (
+ f"Object type mismatch in limited API annotation for {name}: "
+ f"{ROLE_TO_OBJECT_TYPE[record.role]!r} != {objtype!r}"
+ )
+ raise ValueError(msg)
+ annotation = _stable_abi_annotation(record)
+ node.insert(0, annotation)
+
+ # Unstable API annotation.
+ if name.startswith("PyUnstable"):
+ annotation = _unstable_api_annotation()
+ node.insert(0, annotation)
+
+ # Return value annotation
+ if objtype != "function":
+ continue
+ if name not in refcount_data:
+ continue
+ entry = refcount_data[name]
+ if not entry.result_type.endswith("Object*"):
+ continue
+ annotation = _return_value_annotation(entry.result_refs)
+ node.insert(0, annotation)
+
+
+def _stable_abi_annotation(record: StableABIEntry) -> nodes.emphasis:
+ """Create the Stable ABI annotation.
+
+ These have two forms:
+ Part of the `Stable ABI `_.
+ Part of the `Stable ABI `_ since version X.Y.
+ For structs, there's some more info in the message:
+ Part of the `Limited API `_ (as an opaque struct).
+ Part of the `Stable ABI `_ (including all members).
+ Part of the `Limited API `_ (Only some members are part
+ of the stable ABI.).
+ ... all of which can have "since version X.Y" appended.
+ """
+ stable_added = record.added
+ message = sphinx_gettext("Part of the")
+ message = message.center(len(message) + 2)
+ emph_node = nodes.emphasis(message, message, classes=["stableabi"])
+ ref_node = addnodes.pending_xref(
+ "Stable ABI",
+ refdomain="std",
+ reftarget="stable",
+ reftype="ref",
+ refexplicit="False",
+ )
+ struct_abi_kind = record.struct_abi_kind
+ if struct_abi_kind in {"opaque", "members"}:
+ ref_node += nodes.Text(sphinx_gettext("Limited API"))
+ else:
+ ref_node += nodes.Text(sphinx_gettext("Stable ABI"))
+ emph_node += ref_node
+ if struct_abi_kind == "opaque":
+ emph_node += nodes.Text(" " + sphinx_gettext("(as an opaque struct)"))
+ elif struct_abi_kind == "full-abi":
+ emph_node += nodes.Text(
+ " " + sphinx_gettext("(including all members)")
+ )
+ if record.ifdef_note:
+ emph_node += nodes.Text(f" {record.ifdef_note}")
+ if stable_added == "3.2":
+ # Stable ABI was introduced in 3.2.
+ pass
+ else:
+ emph_node += nodes.Text(
+ " " + sphinx_gettext("since version %s") % stable_added
+ )
+ emph_node += nodes.Text(".")
+ if struct_abi_kind == "members":
+ msg = " " + sphinx_gettext(
+ "(Only some members are part of the stable ABI.)"
+ )
+ emph_node += nodes.Text(msg)
+ return emph_node
+
+
+def _unstable_api_annotation() -> nodes.admonition:
+ ref_node = addnodes.pending_xref(
+ "Unstable API",
+ nodes.Text(sphinx_gettext("Unstable API")),
+ refdomain="std",
+ reftarget="unstable-c-api",
+ reftype="ref",
+ refexplicit="False",
+ )
+ emph_node = nodes.emphasis(
+ "This is ",
+ sphinx_gettext("This is") + " ",
+ ref_node,
+ nodes.Text(
+ sphinx_gettext(
+ ". It may change without warning in minor releases."
+ )
+ ),
+ )
+ return nodes.admonition(
+ "",
+ emph_node,
+ classes=["unstable-c-api", "warning"],
)
- app.connect('doctree-read', annotations.add_annotations)
- class LimitedAPIList(Directive):
- has_content = False
- required_arguments = 0
- optional_arguments = 0
- final_argument_whitespace = True
+def _return_value_annotation(result_refs: int | None) -> nodes.emphasis:
+ classes = ["refcount"]
+ if result_refs is None:
+ rc = sphinx_gettext("Return value: Always NULL.")
+ classes.append("return_null")
+ elif result_refs:
+ rc = sphinx_gettext("Return value: New reference.")
+ classes.append("return_new_ref")
+ else:
+ rc = sphinx_gettext("Return value: Borrowed reference.")
+ classes.append("return_borrowed_ref")
+ return nodes.emphasis(rc, rc, classes=classes)
+
+
+class LimitedAPIList(SphinxDirective):
+ has_content = False
+ required_arguments = 0
+ optional_arguments = 0
+ final_argument_whitespace = True
- def run(self):
- content = []
- for record in annotations.stable_abi_data.values():
- role = REST_ROLE_MAP[record['role']]
- name = record['name']
- content.append(f'* :c:{role}:`{name}`')
+ def run(self) -> list[nodes.Node]:
+ state = self.env.domaindata["c_annotations"]
+ content = [
+ f"* :c:{record.role}:`{record.name}`"
+ for record in state["stable_abi_data"].values()
+ ]
+ node = nodes.paragraph()
+ self.state.nested_parse(StringList(content), 0, node)
+ return [node]
- pnode = nodes.paragraph()
- self.state.nested_parse(StringList(content), 0, pnode)
- return [pnode]
- app.add_directive('limited-api-list', LimitedAPIList)
+def init_annotations(app: Sphinx) -> None:
+ # Using domaindata is a bit hack-ish,
+ # but allows storing state without a global variable or closure.
+ app.env.domaindata["c_annotations"] = state = {}
+ state["refcount_data"] = read_refcount_data(
+ Path(app.srcdir, app.config.refcount_file)
+ )
+ state["stable_abi_data"] = read_stable_abi_data(
+ Path(app.srcdir, app.config.stable_abi_file)
+ )
-def setup(app):
- app.add_config_value('refcount_file', '', True)
- app.add_config_value('stable_abi_file', '', True)
- app.connect('builder-inited', init_annotations)
+def setup(app: Sphinx) -> ExtensionMetadata:
+ app.add_config_value("refcount_file", "", "env", types={str})
+ app.add_config_value("stable_abi_file", "", "env", types={str})
+ app.add_directive("limited-api-list", LimitedAPIList)
+ app.connect("builder-inited", init_annotations)
+ app.connect("doctree-read", add_annotations)
- # monkey-patch C object...
- CObject.option_spec = {
- 'noindex': directives.flag,
- 'stableabi': directives.flag,
- }
- old_handle_signature = CObject.handle_signature
+ if sphinx.version_info[:2] < (7, 2):
+ from docutils.parsers.rst import directives
+ from sphinx.domains.c import CObject
- def new_handle_signature(self, sig, signode):
- signode.parent['stableabi'] = 'stableabi' in self.options
- return old_handle_signature(self, sig, signode)
- CObject.handle_signature = new_handle_signature
- return {'version': '1.0', 'parallel_read_safe': True}
+ # monkey-patch C object...
+ CObject.option_spec |= {
+ "no-index-entry": directives.flag,
+ "no-contents-entry": directives.flag,
+ }
+
+ return {
+ "version": "1.0",
+ "parallel_read_safe": True,
+ "parallel_write_safe": True,
+ }
diff --git a/Doc/tools/extensions/escape4chm.py b/Doc/tools/extensions/escape4chm.py
deleted file mode 100644
index 89970975b9032b..00000000000000
--- a/Doc/tools/extensions/escape4chm.py
+++ /dev/null
@@ -1,58 +0,0 @@
-"""
-Escape the `body` part of .chm source file to 7-bit ASCII, to fix visual
-effect on some MBCS Windows systems.
-
-https://bugs.python.org/issue32174
-"""
-
-import pathlib
-import re
-from html.entities import codepoint2name
-
-from sphinx.util.logging import getLogger
-
-# escape the characters which codepoint > 0x7F
-def _process(string):
- def escape(matchobj):
- codepoint = ord(matchobj.group(0))
-
- name = codepoint2name.get(codepoint)
- if name is None:
- return '%d;' % codepoint
- else:
- return '&%s;' % name
-
- return re.sub(r'[^\x00-\x7F]', escape, string)
-
-def escape_for_chm(app, pagename, templatename, context, doctree):
- # only works for .chm output
- if getattr(app.builder, 'name', '') != 'htmlhelp':
- return
-
- # escape the `body` part to 7-bit ASCII
- body = context.get('body')
- if body is not None:
- context['body'] = _process(body)
-
-def fixup_keywords(app, exception):
- # only works for .chm output
- if getattr(app.builder, 'name', '') != 'htmlhelp' or exception:
- return
-
- getLogger(__name__).info('fixing HTML escapes in keywords file...')
- outdir = pathlib.Path(app.builder.outdir)
- outname = app.builder.config.htmlhelp_basename
- with open(outdir / (outname + '.hhk'), 'rb') as f:
- index = f.read()
- with open(outdir / (outname + '.hhk'), 'wb') as f:
- f.write(index.replace(b''', b'''))
-
-def setup(app):
- # `html-page-context` event emitted when the HTML builder has
- # created a context dictionary to render a template with.
- app.connect('html-page-context', escape_for_chm)
- # `build-finished` event emitted when all the files have been
- # output.
- app.connect('build-finished', fixup_keywords)
-
- return {'version': '1.0', 'parallel_read_safe': True}
diff --git a/Doc/tools/extensions/glossary_search.py b/Doc/tools/extensions/glossary_search.py
index 7c93b1e4990603..502b6cd95bcb94 100644
--- a/Doc/tools/extensions/glossary_search.py
+++ b/Doc/tools/extensions/glossary_search.py
@@ -1,63 +1,63 @@
-# -*- coding: utf-8 -*-
-"""
- glossary_search.py
- ~~~~~~~~~~~~~~~~
+"""Feature search results for glossary items prominently."""
- Feature search results for glossary items prominently.
+from __future__ import annotations
- :license: Python license.
-"""
import json
-import os.path
-from docutils.nodes import definition_list_item
+from pathlib import Path
+from typing import TYPE_CHECKING
+
+from docutils import nodes
from sphinx.addnodes import glossary
from sphinx.util import logging
+if TYPE_CHECKING:
+ from sphinx.application import Sphinx
+ from sphinx.util.typing import ExtensionMetadata
logger = logging.getLogger(__name__)
-STATIC_DIR = '_static'
-JSON = 'glossary.json'
-def process_glossary_nodes(app, doctree, fromdocname):
+def process_glossary_nodes(
+ app: Sphinx,
+ doctree: nodes.document,
+ _docname: str,
+) -> None:
if app.builder.format != 'html' or app.builder.embedded:
return
- terms = {}
+ if hasattr(app.env, 'glossary_terms'):
+ terms = app.env.glossary_terms
+ else:
+ terms = app.env.glossary_terms = {}
for node in doctree.findall(glossary):
- for glossary_item in node.findall(definition_list_item):
- term = glossary_item[0].astext().lower()
- definition = glossary_item[1]
+ for glossary_item in node.findall(nodes.definition_list_item):
+ term = glossary_item[0].astext()
+ definition = glossary_item[-1]
rendered = app.builder.render_partial(definition)
- terms[term] = {
- 'title': glossary_item[0].astext(),
- 'body': rendered['html_body']
+ terms[term.lower()] = {
+ 'title': term,
+ 'body': rendered['html_body'],
}
- if hasattr(app.env, 'glossary_terms'):
- app.env.glossary_terms.update(terms)
- else:
- app.env.glossary_terms = terms
-def on_build_finish(app, exc):
- if not hasattr(app.env, 'glossary_terms'):
- return
- if not app.env.glossary_terms:
+def write_glossary_json(app: Sphinx, _exc: Exception) -> None:
+ if not getattr(app.env, 'glossary_terms', None):
return
- logger.info(f'Writing {JSON}', color='green')
-
- dest_dir = os.path.join(app.outdir, STATIC_DIR)
- os.makedirs(dest_dir, exist_ok=True)
-
- with open(os.path.join(dest_dir, JSON), 'w') as f:
- json.dump(app.env.glossary_terms, f)
+ logger.info('Writing glossary.json', color='green')
+ dest = Path(app.outdir, '_static', 'glossary.json')
+ dest.parent.mkdir(exist_ok=True)
+ dest.write_text(json.dumps(app.env.glossary_terms), encoding='utf-8')
-def setup(app):
+def setup(app: Sphinx) -> ExtensionMetadata:
app.connect('doctree-resolved', process_glossary_nodes)
- app.connect('build-finished', on_build_finish)
+ app.connect('build-finished', write_glossary_json)
- return {'version': '0.1', 'parallel_read_safe': True}
+ return {
+ 'version': '1.0',
+ 'parallel_read_safe': True,
+ 'parallel_write_safe': True,
+ }
diff --git a/Doc/tools/extensions/lexers/__init__.py b/Doc/tools/extensions/lexers/__init__.py
new file mode 100644
index 00000000000000..e12ac5be8139cc
--- /dev/null
+++ b/Doc/tools/extensions/lexers/__init__.py
@@ -0,0 +1,15 @@
+from .asdl_lexer import ASDLLexer
+from .peg_lexer import PEGLexer
+
+
+def setup(app):
+ # Used for highlighting Parser/Python.asdl in library/ast.rst
+ app.add_lexer("asdl", ASDLLexer)
+ # Used for highlighting Grammar/python.gram in reference/grammar.rst
+ app.add_lexer("peg", PEGLexer)
+
+ return {
+ "version": "1.0",
+ "parallel_read_safe": True,
+ "parallel_write_safe": True,
+ }
diff --git a/Doc/tools/extensions/asdl_highlight.py b/Doc/tools/extensions/lexers/asdl_lexer.py
similarity index 62%
rename from Doc/tools/extensions/asdl_highlight.py
rename to Doc/tools/extensions/lexers/asdl_lexer.py
index 42863a4b3bcd6a..3a74174a1f7dfb 100644
--- a/Doc/tools/extensions/asdl_highlight.py
+++ b/Doc/tools/extensions/lexers/asdl_lexer.py
@@ -1,15 +1,6 @@
-import sys
-from pathlib import Path
+from pygments.lexer import RegexLexer, bygroups, include
+from pygments.token import Comment, Keyword, Name, Operator, Punctuation, Text
-CPYTHON_ROOT = Path(__file__).resolve().parent.parent.parent.parent
-sys.path.append(str(CPYTHON_ROOT / "Parser"))
-
-from pygments.lexer import RegexLexer, bygroups, include, words
-from pygments.token import (Comment, Keyword, Name, Operator,
- Punctuation, Text)
-
-from asdl import builtin_types
-from sphinx.highlighting import lexers
class ASDLLexer(RegexLexer):
name = "ASDL"
@@ -34,7 +25,10 @@ class ASDLLexer(RegexLexer):
r"(\w+)(\*\s|\?\s|\s)(\w+)",
bygroups(Name.Builtin.Pseudo, Operator, Name),
),
- (words(builtin_types), Name.Builtin),
+ # Keep in line with ``builtin_types`` from Parser/asdl.py.
+ # ASDL's 4 builtin types are
+ # constant, identifier, int, string
+ ("constant|identifier|int|string", Name.Builtin),
(r"attributes", Name.Builtin),
(
_name + _text_ws + "(=)",
@@ -46,8 +40,3 @@ class ASDLLexer(RegexLexer):
(r".", Text),
],
}
-
-
-def setup(app):
- lexers["asdl"] = ASDLLexer()
- return {'version': '1.0', 'parallel_read_safe': True}
diff --git a/Doc/tools/extensions/peg_highlight.py b/Doc/tools/extensions/lexers/peg_lexer.py
similarity index 94%
rename from Doc/tools/extensions/peg_highlight.py
rename to Doc/tools/extensions/lexers/peg_lexer.py
index 5ab5530d269901..06f9f8eb312125 100644
--- a/Doc/tools/extensions/peg_highlight.py
+++ b/Doc/tools/extensions/lexers/peg_lexer.py
@@ -1,8 +1,6 @@
from pygments.lexer import RegexLexer, bygroups, include
from pygments.token import Comment, Keyword, Name, Operator, Punctuation, Text
-from sphinx.highlighting import lexers
-
class PEGLexer(RegexLexer):
"""Pygments Lexer for PEG grammar (.gram) files
@@ -81,8 +79,3 @@ class PEGLexer(RegexLexer):
(r".", Text),
],
}
-
-
-def setup(app):
- lexers["peg"] = PEGLexer()
- return {"version": "1.0", "parallel_read_safe": True}
diff --git a/Doc/tools/extensions/patchlevel.py b/Doc/tools/extensions/patchlevel.py
index 617f28c2527ddf..f2df6db47a2227 100644
--- a/Doc/tools/extensions/patchlevel.py
+++ b/Doc/tools/extensions/patchlevel.py
@@ -1,68 +1,77 @@
-# -*- coding: utf-8 -*-
-"""
- patchlevel.py
- ~~~~~~~~~~~~~
+"""Extract version information from Include/patchlevel.h."""
- Extract version info from Include/patchlevel.h.
- Adapted from Doc/tools/getversioninfo.
+import re
+import sys
+from pathlib import Path
+from typing import Literal, NamedTuple
- :copyright: 2007-2008 by Georg Brandl.
- :license: Python license.
-"""
+CPYTHON_ROOT = Path(
+ __file__, # cpython/Doc/tools/extensions/patchlevel.py
+ "..", # cpython/Doc/tools/extensions
+ "..", # cpython/Doc/tools
+ "..", # cpython/Doc
+ "..", # cpython
+).resolve()
+PATCHLEVEL_H = CPYTHON_ROOT / "Include" / "patchlevel.h"
-from __future__ import print_function
+RELEASE_LEVELS = {
+ "PY_RELEASE_LEVEL_ALPHA": "alpha",
+ "PY_RELEASE_LEVEL_BETA": "beta",
+ "PY_RELEASE_LEVEL_GAMMA": "candidate",
+ "PY_RELEASE_LEVEL_FINAL": "final",
+}
-import os
-import re
-import sys
-def get_header_version_info(srcdir):
- patchlevel_h = os.path.join(srcdir, '..', 'Include', 'patchlevel.h')
+class version_info(NamedTuple): # noqa: N801
+ major: int #: Major release number
+ minor: int #: Minor release number
+ micro: int #: Patch release number
+ releaselevel: Literal["alpha", "beta", "candidate", "final"]
+ serial: int #: Serial release number
- # This won't pick out all #defines, but it will pick up the ones we
- # care about.
- rx = re.compile(r'\s*#define\s+([a-zA-Z][a-zA-Z_0-9]*)\s+([a-zA-Z_0-9]+)')
- d = {}
- with open(patchlevel_h) as f:
- for line in f:
- m = rx.match(line)
- if m is not None:
- name, value = m.group(1, 2)
- d[name] = value
+def get_header_version_info() -> version_info:
+ # Capture PY_ prefixed #defines.
+ pat = re.compile(r"\s*#define\s+(PY_\w*)\s+(\w+)", re.ASCII)
- release = version = '%s.%s' % (d['PY_MAJOR_VERSION'], d['PY_MINOR_VERSION'])
- micro = int(d['PY_MICRO_VERSION'])
- release += '.' + str(micro)
+ defines = {}
+ patchlevel_h = PATCHLEVEL_H.read_text(encoding="utf-8")
+ for line in patchlevel_h.splitlines():
+ if (m := pat.match(line)) is not None:
+ name, value = m.groups()
+ defines[name] = value
- level = d['PY_RELEASE_LEVEL']
- suffixes = {
- 'PY_RELEASE_LEVEL_ALPHA': 'a',
- 'PY_RELEASE_LEVEL_BETA': 'b',
- 'PY_RELEASE_LEVEL_GAMMA': 'rc',
- }
- if level != 'PY_RELEASE_LEVEL_FINAL':
- release += suffixes[level] + str(int(d['PY_RELEASE_SERIAL']))
- return version, release
+ return version_info(
+ major=int(defines["PY_MAJOR_VERSION"]),
+ minor=int(defines["PY_MINOR_VERSION"]),
+ micro=int(defines["PY_MICRO_VERSION"]),
+ releaselevel=RELEASE_LEVELS[defines["PY_RELEASE_LEVEL"]],
+ serial=int(defines["PY_RELEASE_SERIAL"]),
+ )
-def get_sys_version_info():
- major, minor, micro, level, serial = sys.version_info
- release = version = '%s.%s' % (major, minor)
- release += '.%s' % micro
- if level != 'final':
- release += '%s%s' % (level[0], serial)
+def format_version_info(info: version_info) -> tuple[str, str]:
+ version = f"{info.major}.{info.minor}"
+ release = f"{info.major}.{info.minor}.{info.micro}"
+ if info.releaselevel != "final":
+ suffix = {"alpha": "a", "beta": "b", "candidate": "rc"}
+ release += f"{suffix[info.releaselevel]}{info.serial}"
return version, release
def get_version_info():
try:
- return get_header_version_info('.')
- except (IOError, OSError):
- version, release = get_sys_version_info()
- print('Can\'t get version info from Include/patchlevel.h, ' \
- 'using version of this interpreter (%s).' % release, file=sys.stderr)
+ info = get_header_version_info()
+ return format_version_info(info)
+ except OSError:
+ version, release = format_version_info(sys.version_info)
+ print(
+ f"Failed to get version info from Include/patchlevel.h, "
+ f"using version of this interpreter ({release}).",
+ file=sys.stderr,
+ )
return version, release
-if __name__ == '__main__':
- print(get_header_version_info('.')[1])
+
+if __name__ == "__main__":
+ print(format_version_info(get_header_version_info())[1])
diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py
index caf145997fa996..96a4f24fad33b7 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -15,14 +15,14 @@
from time import asctime
from pprint import pformat
-from docutils import nodes, utils
+from docutils import nodes
from docutils.io import StringOutput
-from docutils.parsers.rst import Directive
-from docutils.utils import new_document
+from docutils.parsers.rst import directives
+from docutils.utils import new_document, unescape
from sphinx import addnodes
from sphinx.builders import Builder
-from sphinx.domains.python import PyFunction, PyMethod
-from sphinx.errors import NoUri
+from sphinx.domains.changeset import VersionChange, versionlabels, versionlabel_classes
+from sphinx.domains.python import PyFunction, PyMethod, PyModule
from sphinx.locale import _ as sphinx_gettext
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
@@ -48,11 +48,14 @@
std.token_re = re.compile(r'`((~?[\w-]*:)?\w+)`')
+# backport :no-index:
+PyModule.option_spec['no-index'] = directives.flag
+
# Support for marking up and linking to bugs.python.org issues
def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
- issue = utils.unescape(text)
+ issue = unescape(text)
# sanity check: there are no bpo issues within these two values
if 47261 < int(issue) < 400000:
msg = inliner.reporter.error(f'The BPO ID {text!r} seems too high -- '
@@ -67,7 +70,7 @@ def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
# Support for marking up and linking to GitHub issues
def gh_issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
- issue = utils.unescape(text)
+ issue = unescape(text)
# sanity check: all GitHub issues have ID >= 32426
# even though some of them are also valid BPO IDs
if int(issue) < 32426:
@@ -82,7 +85,7 @@ def gh_issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
# Support for marking up implementation details
-class ImplementationDetail(Directive):
+class ImplementationDetail(SphinxDirective):
has_content = True
final_argument_whitespace = True
@@ -179,143 +182,6 @@ def parse_platforms(self):
return platforms
-# Support for documenting audit event
-
-def audit_events_purge(app, env, docname):
- """This is to remove from env.all_audit_events old traces of removed
- documents.
- """
- if not hasattr(env, 'all_audit_events'):
- return
- fresh_all_audit_events = {}
- for name, event in env.all_audit_events.items():
- event["source"] = [(d, t) for d, t in event["source"] if d != docname]
- if event["source"]:
- # Only keep audit_events that have at least one source.
- fresh_all_audit_events[name] = event
- env.all_audit_events = fresh_all_audit_events
-
-
-def audit_events_merge(app, env, docnames, other):
- """In Sphinx parallel builds, this merges env.all_audit_events from
- subprocesses.
-
- all_audit_events is a dict of names, with values like:
- {'source': [(docname, target), ...], 'args': args}
- """
- if not hasattr(other, 'all_audit_events'):
- return
- if not hasattr(env, 'all_audit_events'):
- env.all_audit_events = {}
- for name, value in other.all_audit_events.items():
- if name in env.all_audit_events:
- env.all_audit_events[name]["source"].extend(value["source"])
- else:
- env.all_audit_events[name] = value
-
-
-class AuditEvent(Directive):
-
- has_content = True
- required_arguments = 1
- optional_arguments = 2
- final_argument_whitespace = True
-
- _label = [
- sphinx_gettext("Raises an :ref:`auditing event ` {name} with no arguments."),
- sphinx_gettext("Raises an :ref:`auditing event ` {name} with argument {args}."),
- sphinx_gettext("Raises an :ref:`auditing event ` {name} with arguments {args}."),
- ]
-
- @property
- def logger(self):
- cls = type(self)
- return logging.getLogger(cls.__module__ + "." + cls.__name__)
-
- def run(self):
- name = self.arguments[0]
- if len(self.arguments) >= 2 and self.arguments[1]:
- args = (a.strip() for a in self.arguments[1].strip("'\"").split(","))
- args = [a for a in args if a]
- else:
- args = []
-
- label = self._label[min(2, len(args))]
- text = label.format(name="``{}``".format(name),
- args=", ".join("``{}``".format(a) for a in args if a))
-
- env = self.state.document.settings.env
- if not hasattr(env, 'all_audit_events'):
- env.all_audit_events = {}
-
- new_info = {
- 'source': [],
- 'args': args
- }
- info = env.all_audit_events.setdefault(name, new_info)
- if info is not new_info:
- if not self._do_args_match(info['args'], new_info['args']):
- self.logger.warning(
- "Mismatched arguments for audit-event {}: {!r} != {!r}"
- .format(name, info['args'], new_info['args'])
- )
-
- ids = []
- try:
- target = self.arguments[2].strip("\"'")
- except (IndexError, TypeError):
- target = None
- if not target:
- target = "audit_event_{}_{}".format(
- re.sub(r'\W', '_', name),
- len(info['source']),
- )
- ids.append(target)
-
- info['source'].append((env.docname, target))
-
- pnode = nodes.paragraph(text, classes=["audit-hook"], ids=ids)
- pnode.line = self.lineno
- if self.content:
- self.state.nested_parse(self.content, self.content_offset, pnode)
- else:
- n, m = self.state.inline_text(text, self.lineno)
- pnode.extend(n + m)
-
- return [pnode]
-
- # This list of sets are allowable synonyms for event argument names.
- # If two names are in the same set, they are treated as equal for the
- # purposes of warning. This won't help if number of arguments is
- # different!
- _SYNONYMS = [
- {"file", "path", "fd"},
- ]
-
- def _do_args_match(self, args1, args2):
- if args1 == args2:
- return True
- if len(args1) != len(args2):
- return False
- for a1, a2 in zip(args1, args2):
- if a1 == a2:
- continue
- if any(a1 in s and a2 in s for s in self._SYNONYMS):
- continue
- return False
- return True
-
-
-class audit_event_list(nodes.General, nodes.Element):
- pass
-
-
-class AuditEventListDirective(Directive):
-
- def run(self):
- return [audit_event_list('')]
-
-
# Support for documenting decorators
class PyDecoratorMixin(object):
@@ -395,58 +261,34 @@ def run(self):
# Support for documenting version of removal in deprecations
-class DeprecatedRemoved(Directive):
- has_content = True
+class DeprecatedRemoved(VersionChange):
required_arguments = 2
- optional_arguments = 1
- final_argument_whitespace = True
- option_spec = {}
- _deprecated_label = sphinx_gettext('Deprecated since version {deprecated}, will be removed in version {removed}')
- _removed_label = sphinx_gettext('Deprecated since version {deprecated}, removed in version {removed}')
+ _deprecated_label = sphinx_gettext('Deprecated since version %s, will be removed in version %s')
+ _removed_label = sphinx_gettext('Deprecated since version %s, removed in version %s')
def run(self):
- node = addnodes.versionmodified()
- node.document = self.state.document
- node['type'] = 'deprecated-removed'
- version = (self.arguments[0], self.arguments[1])
- node['version'] = version
- env = self.state.document.settings.env
- current_version = tuple(int(e) for e in env.config.version.split('.'))
- removed_version = tuple(int(e) for e in self.arguments[1].split('.'))
+ # Replace the first two arguments (deprecated version and removed version)
+ # with a single tuple of both versions.
+ version_deprecated = self.arguments[0]
+ version_removed = self.arguments.pop(1)
+ self.arguments[0] = version_deprecated, version_removed
+
+ # Set the label based on if we have reached the removal version
+ current_version = tuple(map(int, self.config.version.split('.')))
+ removed_version = tuple(map(int, version_removed.split('.')))
if current_version < removed_version:
- label = self._deprecated_label
- else:
- label = self._removed_label
-
- text = label.format(deprecated=self.arguments[0], removed=self.arguments[1])
- if len(self.arguments) == 3:
- inodes, messages = self.state.inline_text(self.arguments[2],
- self.lineno+1)
- para = nodes.paragraph(self.arguments[2], '', *inodes, translatable=False)
- node.append(para)
+ versionlabels[self.name] = self._deprecated_label
+ versionlabel_classes[self.name] = 'deprecated'
else:
- messages = []
- if self.content:
- self.state.nested_parse(self.content, self.content_offset, node)
- if len(node):
- if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
- content = nodes.inline(node[0].rawsource, translatable=True)
- content.source = node[0].source
- content.line = node[0].line
- content += node[0].children
- node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
- node[0].insert(0, nodes.inline('', '%s: ' % text,
- classes=['versionmodified']))
- else:
- para = nodes.paragraph('', '',
- nodes.inline('', '%s.' % text,
- classes=['versionmodified']),
- translatable=False)
- node.append(para)
- env = self.state.document.settings.env
- env.get_domain('changeset').note_changeset(node)
- return [node] + messages
+ versionlabels[self.name] = self._removed_label
+ versionlabel_classes[self.name] = 'removed'
+ try:
+ return super().run()
+ finally:
+ # reset versionlabels and versionlabel_classes
+ versionlabels[self.name] = ''
+ versionlabel_classes[self.name] = ''
# Support for including Misc/NEWS
@@ -456,7 +298,7 @@ def run(self):
whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$")
-class MiscNews(Directive):
+class MiscNews(SphinxDirective):
has_content = False
required_arguments = 1
optional_arguments = 0
@@ -471,7 +313,7 @@ def run(self):
if not source_dir:
source_dir = path.dirname(path.abspath(source))
fpath = path.join(source_dir, fname)
- self.state.document.settings.record_dependencies.add(fpath)
+ self.env.note_dependency(path.abspath(fpath))
try:
with io.open(fpath, encoding='utf-8') as fp:
content = fp.read()
@@ -603,70 +445,6 @@ def parse_monitoring_event(env, sig, signode):
return sig
-def process_audit_events(app, doctree, fromdocname):
- for node in doctree.findall(audit_event_list):
- break
- else:
- return
-
- env = app.builder.env
-
- table = nodes.table(cols=3)
- group = nodes.tgroup(
- '',
- nodes.colspec(colwidth=30),
- nodes.colspec(colwidth=55),
- nodes.colspec(colwidth=15),
- cols=3,
- )
- head = nodes.thead()
- body = nodes.tbody()
-
- table += group
- group += head
- group += body
-
- row = nodes.row()
- row += nodes.entry('', nodes.paragraph('', nodes.Text('Audit event')))
- row += nodes.entry('', nodes.paragraph('', nodes.Text('Arguments')))
- row += nodes.entry('', nodes.paragraph('', nodes.Text('References')))
- head += row
-
- for name in sorted(getattr(env, "all_audit_events", ())):
- audit_event = env.all_audit_events[name]
-
- row = nodes.row()
- node = nodes.paragraph('', nodes.Text(name))
- row += nodes.entry('', node)
-
- node = nodes.paragraph()
- for i, a in enumerate(audit_event['args']):
- if i:
- node += nodes.Text(", ")
- node += nodes.literal(a, nodes.Text(a))
- row += nodes.entry('', node)
-
- node = nodes.paragraph()
- backlinks = enumerate(sorted(set(audit_event['source'])), start=1)
- for i, (doc, label) in backlinks:
- if isinstance(label, str):
- ref = nodes.reference("", nodes.Text("[{}]".format(i)), internal=True)
- try:
- ref['refuri'] = "{}#{}".format(
- app.builder.get_relative_uri(fromdocname, doc),
- label,
- )
- except NoUri:
- continue
- node += ref
- row += nodes.entry('', node)
-
- body += row
-
- for node in doctree.findall(audit_event_list):
- node.replace_self(table)
-
-
def patch_pairindextypes(app, _env) -> None:
"""Remove all entries from ``pairindextypes`` before writing POT files.
@@ -696,8 +474,6 @@ def setup(app):
app.add_role('gh', gh_issue_role)
app.add_directive('impl-detail', ImplementationDetail)
app.add_directive('availability', Availability)
- app.add_directive('audit-event', AuditEvent)
- app.add_directive('audit-event-table', AuditEventListDirective)
app.add_directive('deprecated-removed', DeprecatedRemoved)
app.add_builder(PydocTopicsBuilder)
app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature)
@@ -713,7 +489,4 @@ def setup(app):
app.add_directive_to_domain('py', 'abstractmethod', PyAbstractMethod)
app.add_directive('miscnews', MiscNews)
app.connect('env-check-consistency', patch_pairindextypes)
- app.connect('doctree-resolved', process_audit_events)
- app.connect('env-merge-info', audit_events_merge)
- app.connect('env-purge-doc', audit_events_purge)
return {'version': '1.0', 'parallel_read_safe': True}
diff --git a/Doc/tools/static/glossary_search.js b/Doc/tools/static/glossary_search.js
new file mode 100644
index 00000000000000..13d728dc027f1d
--- /dev/null
+++ b/Doc/tools/static/glossary_search.js
@@ -0,0 +1,47 @@
+"use strict";
+
+const GLOSSARY_PAGE = "glossary.html";
+
+const glossary_search = async () => {
+ const response = await fetch("_static/glossary.json");
+ if (!response.ok) {
+ throw new Error("Failed to fetch glossary.json");
+ }
+ const glossary = await response.json();
+
+ const params = new URLSearchParams(document.location.search).get("q");
+ if (!params) {
+ return;
+ }
+
+ const searchParam = params.toLowerCase();
+ const glossaryItem = glossary[searchParam];
+ if (!glossaryItem) {
+ return;
+ }
+
+ // set up the title text with a link to the glossary page
+ const glossaryTitle = document.getElementById("glossary-title");
+ glossaryTitle.textContent = "Glossary: " + glossaryItem.title;
+ const linkTarget = searchParam.replace(/ /g, "-");
+ glossaryTitle.href = GLOSSARY_PAGE + "#term-" + linkTarget;
+
+ // rewrite any anchor links (to other glossary terms)
+ // to have a full reference to the glossary page
+ const glossaryBody = document.getElementById("glossary-body");
+ glossaryBody.innerHTML = glossaryItem.body;
+ const anchorLinks = glossaryBody.querySelectorAll('a[href^="#"]');
+ anchorLinks.forEach(function (link) {
+ const currentUrl = link.getAttribute("href");
+ link.href = GLOSSARY_PAGE + currentUrl;
+ });
+
+ const glossaryResult = document.getElementById("glossary-result");
+ glossaryResult.style.display = "";
+};
+
+if (document.readyState !== "loading") {
+ glossary_search().catch(console.error);
+} else {
+ document.addEventListener("DOMContentLoaded", glossary_search);
+}
diff --git a/Doc/tools/static/rtd_switcher.js b/Doc/tools/static/rtd_switcher.js
new file mode 100644
index 00000000000000..f5dc7045a0dbc4
--- /dev/null
+++ b/Doc/tools/static/rtd_switcher.js
@@ -0,0 +1,55 @@
+ function onSwitch(event) {
+ const option = event.target.selectedIndex;
+ const item = event.target.options[option];
+ window.location.href = item.dataset.url;
+ }
+
+ document.addEventListener("readthedocs-addons-data-ready", function(event) {
+ const config = event.detail.data()
+ const versionSelect = `
+
+ `;
+
+ // Prepend the current language to the options on the selector
+ let languages = config.projects.translations.concat(config.projects.current);
+ languages = languages.sort((a, b) => a.language.name.localeCompare(b.language.name));
+
+ const languageSelect = `
+
+ `;
+
+ // Query all the placeholders because there are different ones for Desktop/Mobile
+ const versionPlaceholders = document.querySelectorAll(".version_switcher_placeholder");
+ for (placeholder of versionPlaceholders) {
+ placeholder.innerHTML = versionSelect;
+ let selectElement = placeholder.querySelector("select");
+ selectElement.addEventListener("change", onSwitch);
+ }
+
+ const languagePlaceholders = document.querySelectorAll(".language_switcher_placeholder");
+ for (placeholder of languagePlaceholders) {
+ placeholder.innerHTML = languageSelect;
+ let selectElement = placeholder.querySelector("select");
+ selectElement.addEventListener("change", onSwitch);
+ }
+ });
diff --git a/Doc/tools/templates/download.html b/Doc/tools/templates/download.html
index b5353d6fb77ab4..9f99eea6f3c773 100644
--- a/Doc/tools/templates/download.html
+++ b/Doc/tools/templates/download.html
@@ -1,5 +1,5 @@
{% extends "layout.html" %}
-{% set title = 'Download' %}
+{% set title = _('Download') %}
{% if daily is defined %}
{% set dlbase = pathto('archives', 1) %}
{% else %}
@@ -11,54 +11,68 @@
{% endif %}
{% block body %}
-
Download Python {{ release }} Documentation
+
{% trans %}Download Python {{ release }} Documentation{% endtrans %}
-{% if last_updated %}
Last updated on: {{ last_updated }}.
{% endif %}
+{% if last_updated %}
{% trans %}Last updated on: {{ last_updated }}.{% endtrans %}
{% endif %}
-
To download an archive containing all the documents for this version of
-Python in one of various formats, follow one of links in this table.
+
{% trans %}To download an archive containing all the documents for this version of
+Python in one of various formats, follow one of links in this table.{% endtrans %}
These archives contain all the content in the documentation.
+
{% trans %}These archives contain all the content in the documentation.{% endtrans %}
-
Unpacking
+
{% trans %}Unpacking{% endtrans %}
-
Unix users should download the .tar.bz2 archives; these are bzipped tar
+
{% trans %}Unix users should download the .tar.bz2 archives; these are bzipped tar
archives and can be handled in the usual way using tar and the bzip2
program. The Info-ZIP unzip program can be
used to handle the ZIP archives if desired. The .tar.bz2 archives provide the
-best compression and fastest download times.
+best compression and fastest download times.{% endtrans %}
-
Windows users can use the ZIP archives since those are customary on that
-platform. These are created on Unix using the Info-ZIP zip program.
+
{% trans %}Windows users can use the ZIP archives since those are customary on that
+platform. These are created on Unix using the Info-ZIP zip program.{% endtrans %}
-
Problems
+
{% trans %}Problems{% endtrans %}
-
If you have comments or suggestions for the Python documentation, please send
-email to docs@python.org.
+
{% trans %}If you have comments or suggestions for the Python documentation, please send
+email to docs@python.org.{% endtrans %}