diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml
new file mode 100644
index 00000000000000..ecb0c8e38f40a0
--- /dev/null
+++ b/.azure-pipelines/ci.yml
@@ -0,0 +1,164 @@
+variables:
+ manylinux: false
+ coverage: false
+
+resources:
+ containers:
+ - container: manylinux1
+ image: pyca/cryptography-manylinux1:x86_64
+
+jobs:
+- job: Prebuild
+ displayName: Pre-build checks
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ steps:
+ - template: ./prebuild-checks.yml
+
+
+- job: Docs_PR
+ displayName: Docs PR
+ dependsOn: Prebuild
+ condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ steps:
+ - template: ./docs-steps.yml
+ parameters:
+ upload: true
+
+
+- job: macOS_CI_Tests
+ displayName: macOS CI Tests
+ dependsOn: Prebuild
+ #condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
+ # bpo-39837: macOS tests on Azure Pipelines are disabled
+ condition: false
+
+ variables:
+ testRunTitle: '$(build.sourceBranchName)-macos'
+ testRunPlatform: macos
+
+ pool:
+ vmImage: macos-10.14
+
+ steps:
+ - template: ./macos-steps.yml
+
+
+- job: Ubuntu_CI_Tests
+ displayName: Ubuntu CI Tests
+ dependsOn: Prebuild
+ condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ variables:
+ testRunTitle: '$(build.sourceBranchName)-linux'
+ testRunPlatform: linux
+ openssl_version: 1.1.1u
+
+ steps:
+ - template: ./posix-steps.yml
+ parameters:
+ dependencies: apt
+
+
+- job: ManyLinux1_CI_Tests
+ displayName: ManyLinux1 CI Tests
+ dependsOn: Prebuild
+ condition: |
+ and(
+ and(
+ succeeded(),
+ eq(variables['manylinux'], 'true')
+ ),
+ eq(dependencies.Prebuild.outputs['tests.run'], 'true')
+ )
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ container: manylinux1
+
+ variables:
+ testRunTitle: '$(build.sourceBranchName)-manylinux1'
+ testRunPlatform: manylinux1
+ openssl_version: ''
+
+ steps:
+ - template: ./posix-steps.yml
+ parameters:
+ dependencies: yum
+ sudo_dependencies: ''
+ xvfb: false
+ patchcheck: false
+
+
+- job: Ubuntu_Coverage_CI_Tests
+ displayName: Ubuntu CI Tests (coverage)
+ dependsOn: Prebuild
+ condition: |
+ and(
+ and(
+ succeeded(),
+ eq(variables['coverage'], 'true')
+ ),
+ eq(dependencies.Prebuild.outputs['tests.run'], 'true')
+ )
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ variables:
+ testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
+ testRunPlatform: linux-coverage
+ openssl_version: 1.1.1u
+
+ steps:
+ - template: ./posix-steps.yml
+ parameters:
+ dependencies: apt
+ coverage: true
+
+
+- job: Windows_CI_Tests
+ displayName: Windows CI Tests
+ dependsOn: Prebuild
+ condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
+
+ pool:
+ vmImage: vs2017-win2016
+
+ strategy:
+ matrix:
+ win32:
+ arch: win32
+ buildOpt: '-p Win32'
+ testRunTitle: '$(Build.SourceBranchName)-win32'
+ testRunPlatform: win32
+ win64:
+ arch: amd64
+ buildOpt: '-p x64'
+ testRunTitle: '$(Build.SourceBranchName)-win64'
+ testRunPlatform: win64
+ maxParallel: 2
+
+ steps:
+ - template: ./windows-steps.yml
+
+ - template: ./windows-layout-steps.yml
+ parameters:
+ kind: nuget
+ - template: ./windows-layout-steps.yml
+ parameters:
+ kind: embed
+ - template: ./windows-layout-steps.yml
+ parameters:
+ kind: appx
+ fulltest: true
diff --git a/.azure-pipelines/docs-steps.yml b/.azure-pipelines/docs-steps.yml
new file mode 100644
index 00000000000000..492e4e34bb2dab
--- /dev/null
+++ b/.azure-pipelines/docs-steps.yml
@@ -0,0 +1,46 @@
+parameters:
+ latex: false
+ upload: false
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- task: UsePythonVersion@0
+ displayName: 'Use Python 3.6 or later'
+ inputs:
+ versionSpec: '>=3.6'
+
+- script: python -m pip install sphinx==1.8.2 blurb python-docs-theme
+ displayName: 'Install build dependencies'
+
+- ${{ if ne(parameters.latex, 'true') }}:
+ - script: make check suspicious html PYTHON=python
+ workingDirectory: '$(build.sourcesDirectory)/Doc'
+ displayName: 'Build documentation'
+
+- ${{ if eq(parameters.latex, 'true') }}:
+ - script: sudo apt-get update && sudo apt-get install -qy --force-yes texlive-full
+ displayName: 'Install LaTeX'
+
+ - script: make dist PYTHON=python SPHINXBUILD='python -m sphinx' BLURB='python -m blurb'
+ workingDirectory: '$(build.sourcesDirectory)/Doc'
+ displayName: 'Build documentation'
+
+- ${{ if eq(parameters.upload, 'true') }}:
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish docs'
+
+ inputs:
+ PathToPublish: '$(build.sourcesDirectory)/Doc/build'
+ ArtifactName: docs
+ publishLocation: Container
+
+ - ${{ if eq(parameters.latex, 'true') }}:
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish dist'
+ inputs:
+ PathToPublish: '$(build.sourcesDirectory)/Doc/dist'
+ ArtifactName: docs_dist
+ publishLocation: Container
diff --git a/.azure-pipelines/macos-steps.yml b/.azure-pipelines/macos-steps.yml
new file mode 100644
index 00000000000000..fa38a0df8c87b8
--- /dev/null
+++ b/.azure-pipelines/macos-steps.yml
@@ -0,0 +1,27 @@
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-azdev
+ displayName: 'Configure CPython (debug)'
+
+- script: make -j4
+ displayName: 'Build CPython'
+
+- script: make pythoninfo
+ displayName: 'Display build info'
+
+- script: make buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml"
+ displayName: 'Tests'
+ continueOnError: true
+ timeoutInMinutes: 30
+
+- task: PublishTestResults@2
+ displayName: 'Publish Test Results'
+ inputs:
+ testResultsFiles: '$(build.binariesDirectory)/test-results.xml'
+ mergeTestResults: true
+ testRunTitle: $(testRunTitle)
+ platform: $(testRunPlatform)
+ condition: succeededOrFailed()
diff --git a/.azure-pipelines/posix-deps-apt.sh b/.azure-pipelines/posix-deps-apt.sh
new file mode 100755
index 00000000000000..4f489903ab569b
--- /dev/null
+++ b/.azure-pipelines/posix-deps-apt.sh
@@ -0,0 +1,26 @@
+apt-get update
+
+apt-get -yq install \
+ build-essential \
+ zlib1g-dev \
+ libbz2-dev \
+ liblzma-dev \
+ libncurses5-dev \
+ libreadline6-dev \
+ libsqlite3-dev \
+ libssl-dev \
+ libgdbm-dev \
+ tk-dev \
+ lzma \
+ lzma-dev \
+ liblzma-dev \
+ libffi-dev \
+ uuid-dev \
+ xvfb
+
+if [ ! -z "$1" ]
+then
+ echo ##vso[task.prependpath]$PWD/multissl/openssl/$1
+ echo ##vso[task.setvariable variable=OPENSSL_DIR]$PWD/multissl/openssl/$1
+ python3 Tools/ssl/multissltests.py --steps=library --base-directory $PWD/multissl --openssl $1 --system Linux
+fi
diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml
new file mode 100644
index 00000000000000..95d3e98fe97c08
--- /dev/null
+++ b/.azure-pipelines/posix-steps.yml
@@ -0,0 +1,81 @@
+parameters:
+ coverage: false
+ sudo_dependencies: sudo
+ dependencies: apt
+ patchcheck: true
+ xvfb: true
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+# Work around a known issue affecting Ubuntu VMs on Pipelines
+- script: sudo setfacl -Rb /home/vsts
+ displayName: 'Workaround ACL issue'
+
+- script: ${{ parameters.sudo_dependencies }} ./.azure-pipelines/posix-deps-${{ parameters.dependencies }}.sh $(openssl_version)
+ displayName: 'Install dependencies'
+
+- script: ./configure --with-pydebug
+ displayName: 'Configure CPython (debug)'
+
+- script: make -j4
+ displayName: 'Build CPython'
+
+- ${{ if eq(parameters.coverage, 'true') }}:
+ - script: ./python -m venv venv && ./venv/bin/python -m pip install -U coverage
+ displayName: 'Set up virtual environment'
+
+ - script: ./venv/bin/python -m test.pythoninfo
+ displayName: 'Display build info'
+
+ - script: |
+ $COMMAND -m coverage run --pylib -m test \
+ --fail-env-changed \
+ -uall,-cpu \
+ --junit-xml=$(build.binariesDirectory)/test-results.xml" \
+ -x test_multiprocessing_fork \
+ -x test_multiprocessing_forkserver \
+ -x test_multiprocessing_spawn \
+ -x test_concurrent_futures
+ displayName: 'Tests with coverage'
+ env:
+ ${{ if eq(parameters.xvfb, 'true') }}:
+ COMMAND: xvfb-run ./venv/bin/python
+ ${{ if ne(parameters.xvfb, 'true') }}:
+ COMMAND: ./venv/bin/python
+
+ - script: ./venv/bin/python -m coverage xml
+ displayName: 'Generate coverage.xml'
+
+ - script: source ./venv/bin/activate && bash <(curl -s https://codecov.io/bash)
+ displayName: 'Publish code coverage results'
+
+
+- ${{ if ne(parameters.coverage, 'true') }}:
+ - script: make pythoninfo
+ displayName: 'Display build info'
+
+ - script: $COMMAND buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml"
+ displayName: 'Tests'
+ env:
+ ${{ if eq(parameters.xvfb, 'true') }}:
+ COMMAND: xvfb-run make
+ ${{ if ne(parameters.xvfb, 'true') }}:
+ COMMAND: make
+
+- ${{ if eq(parameters.patchcheck, 'true') }}:
+ - script: ./python Tools/scripts/patchcheck.py --travis true
+ displayName: 'Run patchcheck.py'
+ condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
+
+
+- task: PublishTestResults@2
+ displayName: 'Publish Test Results'
+ inputs:
+ testResultsFiles: '$(build.binariesDirectory)/test-results.xml'
+ mergeTestResults: true
+ testRunTitle: $(testRunTitle)
+ platform: $(testRunPlatform)
+ condition: succeededOrFailed()
diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml
new file mode 100644
index 00000000000000..da38a81ae0222c
--- /dev/null
+++ b/.azure-pipelines/pr.yml
@@ -0,0 +1,155 @@
+variables:
+ manylinux: false
+ coverage: false
+
+resources:
+ containers:
+ - container: manylinux1
+ image: pyca/cryptography-manylinux1:x86_64
+
+jobs:
+- job: Prebuild
+ displayName: Pre-build checks
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ steps:
+ - template: ./prebuild-checks.yml
+
+
+- job: Docs_PR
+ displayName: Docs PR
+ dependsOn: Prebuild
+ condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ steps:
+ - template: ./docs-steps.yml
+
+
+- job: macOS_PR_Tests
+ displayName: macOS PR Tests
+ dependsOn: Prebuild
+ #condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
+ # bpo-39837: macOS tests on Azure Pipelines are disabled
+ condition: false
+
+ variables:
+ testRunTitle: '$(system.pullRequest.TargetBranch)-macos'
+ testRunPlatform: macos
+
+ pool:
+ vmImage: macos-10.14
+
+ steps:
+ - template: ./macos-steps.yml
+ parameters:
+ targetBranch: $(System.PullRequest.TargetBranch)
+
+
+- job: Ubuntu_PR_Tests
+ displayName: Ubuntu PR Tests
+ dependsOn: Prebuild
+ condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ variables:
+ testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
+ testRunPlatform: linux
+ openssl_version: 1.1.1u
+
+ steps:
+ - template: ./posix-steps.yml
+ parameters:
+ dependencies: apt
+
+
+- job: ManyLinux1_PR_Tests
+ displayName: ManyLinux1 PR Tests
+ dependsOn: Prebuild
+ condition: |
+ and(
+ and(
+ succeeded(),
+ eq(variables['manylinux'], 'true')
+ ),
+ eq(dependencies.Prebuild.outputs['tests.run'], 'true')
+ )
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ container: manylinux1
+
+ variables:
+ testRunTitle: '$(system.pullRequest.TargetBranch)-manylinux1'
+ testRunPlatform: manylinux1
+ openssl_version: ''
+
+ steps:
+ - template: ./posix-steps.yml
+ parameters:
+ dependencies: yum
+ sudo_dependencies: ''
+ xvfb: false
+ patchcheck: false
+
+
+- job: Ubuntu_Coverage_PR_Tests
+ displayName: Ubuntu PR Tests (coverage)
+ dependsOn: Prebuild
+ condition: |
+ and(
+ and(
+ succeeded(),
+ eq(variables['coverage'], 'true')
+ ),
+ eq(dependencies.Prebuild.outputs['tests.run'], 'true')
+ )
+
+ pool:
+ vmImage: ubuntu-20.04
+
+ variables:
+ testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
+ testRunPlatform: linux-coverage
+ openssl_version: 1.1.1u
+
+ steps:
+ - template: ./posix-steps.yml
+ parameters:
+ dependencies: apt
+ coverage: true
+
+
+- job: Windows_PR_Tests
+ displayName: Windows PR Tests
+ dependsOn: Prebuild
+ condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
+
+ pool:
+ vmImage: vs2017-win2016
+
+ strategy:
+ matrix:
+ win32:
+ arch: win32
+ buildOpt: '-p Win32'
+ testRunTitle: '$(System.PullRequest.TargetBranch)-win32'
+ testRunPlatform: win32
+ win64:
+ arch: amd64
+ buildOpt: '-p x64'
+ testRunTitle: '$(System.PullRequest.TargetBranch)-win64'
+ testRunPlatform: win64
+ maxParallel: 2
+
+ steps:
+ - template: ./windows-steps.yml
+ parameters:
+ targetBranch: $(System.PullRequest.TargetBranch)
diff --git a/.azure-pipelines/prebuild-checks.yml b/.azure-pipelines/prebuild-checks.yml
new file mode 100644
index 00000000000000..30ff642d1267a1
--- /dev/null
+++ b/.azure-pipelines/prebuild-checks.yml
@@ -0,0 +1,36 @@
+steps:
+- checkout: self
+ fetchDepth: 5
+
+- script: echo "##vso[task.setvariable variable=diffTarget]HEAD~1"
+ displayName: Set default diff target
+
+- script: |
+ git fetch -q origin $(System.PullRequest.TargetBranch)
+ echo "##vso[task.setvariable variable=diffTarget]HEAD \$(git merge-base HEAD FETCH_HEAD)"
+ displayName: Fetch comparison tree
+ condition: and(succeeded(), variables['System.PullRequest.TargetBranch'])
+
+- script: |
+ if ! git diff --name-only $(diffTarget) | grep -qE '(\.rst$|^Doc|^Misc)'
+ then
+ echo "No docs were updated: docs.run=false"
+ echo "##vso[task.setvariable variable=run;isOutput=true]false"
+ else
+ echo "Docs were updated: docs.run=true"
+ echo "##vso[task.setvariable variable=run;isOutput=true]true"
+ fi
+ displayName: Detect documentation changes
+ name: docs
+
+- script: |
+ if ! git diff --name-only $(diffTarget) | grep -qvE '(\.rst$|^Doc|^Misc)'
+ then
+ echo "Only docs were updated: tests.run=false"
+ echo "##vso[task.setvariable variable=run;isOutput=true]false"
+ else
+ echo "Code was updated: tests.run=true"
+ echo "##vso[task.setvariable variable=run;isOutput=true]true"
+ fi
+ displayName: Detect source changes
+ name: tests
diff --git a/.azure-pipelines/windows-layout-steps.yml b/.azure-pipelines/windows-layout-steps.yml
new file mode 100644
index 00000000000000..e15729fac3443d
--- /dev/null
+++ b/.azure-pipelines/windows-layout-steps.yml
@@ -0,0 +1,28 @@
+parameters:
+ kind: nuget
+ extraOpts: --precompile
+ fulltest: false
+
+steps:
+- script: .\python.bat PC\layout -vv -s "$(Build.SourcesDirectory)" -b "$(Py_OutDir)\$(arch)" -t "$(Build.BinariesDirectory)\layout-tmp-${{ parameters.kind }}-$(arch)" --copy "$(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)" ${{ parameters.extraOpts }} --preset-${{ parameters.kind }} --include-tests
+ displayName: Create ${{ parameters.kind }} layout
+
+- script: .\python.exe -m test.pythoninfo
+ workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
+ displayName: Show layout info (${{ parameters.kind }})
+
+- ${{ if eq(parameters.fulltest, 'true') }}:
+ - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)"
+ workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
+ displayName: ${{ parameters.kind }} Tests
+ env:
+ PREFIX: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
+
+ - task: PublishTestResults@2
+ displayName: Publish ${{ parameters.kind }} Test Results
+ inputs:
+ testResultsFiles: $(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml
+ mergeTestResults: true
+ testRunTitle: ${{ parameters.kind }}-$(testRunTitle)
+ platform: $(testRunPlatform)
+ condition: succeededOrFailed()
diff --git a/.azure-pipelines/windows-steps.yml b/.azure-pipelines/windows-steps.yml
new file mode 100644
index 00000000000000..794a23a5d77e86
--- /dev/null
+++ b/.azure-pipelines/windows-steps.yml
@@ -0,0 +1,35 @@
+steps:
+- checkout: self
+ clean: false
+ fetchDepth: 5
+
+- powershell: |
+ # Relocate build outputs outside of source directory to make cleaning faster
+ Write-Host '##vso[task.setvariable variable=Py_IntDir]$(Build.BinariesDirectory)\obj'
+ # UNDONE: Do not build to a different directory because of broken tests
+ Write-Host '##vso[task.setvariable variable=Py_OutDir]$(Build.SourcesDirectory)\PCbuild'
+ #Write-Host '##vso[task.setvariable variable=Py_OutDir]$(Build.BinariesDirectory)\bin'
+ Write-Host '##vso[task.setvariable variable=EXTERNALS_DIR]$(Build.BinariesDirectory)\externals'
+ displayName: Update build locations
+
+- script: PCbuild\build.bat -e $(buildOpt)
+ displayName: 'Build CPython'
+ env:
+ IncludeUwp: true
+
+- script: python.bat -m test.pythoninfo
+ displayName: 'Display build info'
+
+- script: PCbuild\rt.bat -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results.xml" --tempdir="$(Build.BinariesDirectory)\test"
+ displayName: 'Tests'
+ env:
+ PREFIX: $(Py_OutDir)\$(arch)
+
+- task: PublishTestResults@2
+ displayName: 'Publish Test Results'
+ inputs:
+ testResultsFiles: '$(Build.BinariesDirectory)\test-results.xml'
+ mergeTestResults: true
+ testRunTitle: $(testRunTitle)
+ platform: $(testRunPlatform)
+ condition: succeededOrFailed()
diff --git a/.gitattributes b/.gitattributes
index 0a998a5369fff9..16237bb2b3ac19 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -19,6 +19,7 @@
# Specific binary files
Lib/test/sndhdrdata/sndhdr.* binary
+PC/classicAppCompat.* binary
# Text files that should not be subject to eol conversion
Lib/test/cjkencodings/* -text
@@ -37,3 +38,20 @@ Lib/test/test_importlib/data01/* -text
*.proj text eol=crlf
PCbuild/readme.txt text eol=crlf
PC/readme.txt text eol=crlf
+
+# Generated files
+# https://github.com/github/linguist#generated-code
+Include/graminit.h linguist-generated=true
+Python/graminit.h linguist-generated=true
+Modules/clinic/*.h linguist-generated=true
+Objects/clinic/*.h linguist-generated=true
+PC/clinic/*.h linguist-generated=true
+Python/clinic/*.h linguist-generated=true
+Python/importlib.h linguist-generated=true
+Python/importlib_external.h linguist-generated=true
+Include/Python-ast.h linguist-generated=true
+Python/Python-ast.c linguist-generated=true
+Include/opcode.h linguist-generated=true
+Python/opcode_targets.h linguist-generated=true
+Objects/typeslots.inc linguist-generated=true
+Modules/unicodedata_db.h linguist-generated=true
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 17d7ef4d7a243e..84c534145de8ea 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -18,7 +18,7 @@
# Import (including importlib).
# Ignoring importlib.h so as to not get flagged on
-# all pull requests that change the the emitted
+# all pull requests that change the emitted
# bytecode.
**/*import*.c @python/import-team
**/*import*.py @python/import-team
diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst
index d559bd5e189448..7f912e87084190 100644
--- a/.github/CONTRIBUTING.rst
+++ b/.github/CONTRIBUTING.rst
@@ -8,6 +8,10 @@ Build Status
+ `Stable buildbots `_
+- 3.7
+
+ + `Stable buildbots `_
+
- 3.6
+ `Stable buildbots `_
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 0f238d0558cd00..55e4168747e10d 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,9 +1,11 @@
!!! If this is a backport PR (PR made against branches other than `master`),
please ensure that the PR title is in the following format:
+
```
[X.Y]
(GH-NNNN)
```
-Where: [X.Y] is the branch name, e.g. [3.6].
+
+Where: [X.Y] is the branch name, e.g. [3.7].
GH-NNNN refers to the PR number from `master`.
diff --git a/.github/appveyor.yml b/.github/appveyor.yml
deleted file mode 100644
index b7d40787318985..00000000000000
--- a/.github/appveyor.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-version: 3.7build{build}
-clone_depth: 5
-branches:
- only:
- - master
- - /\d\.\d/
- - buildbot-custom
-cache:
- - externals -> PCbuild\*
-build_script:
-- cmd: PCbuild\build.bat -e
-- cmd: PCbuild\win32\python.exe -m test.pythoninfo
-test_script:
-- cmd: PCbuild\rt.bat -q -uall -u-cpu -rwW --slowest --timeout=1200 --fail-env-changed -j0
-environment:
- HOST_PYTHON: C:\Python36\python.exe
-image:
-- Visual Studio 2017
diff --git a/.github/codecov.yml b/.github/codecov.yml
index 9d97dfbc43f8d0..ea504f48672eac 100644
--- a/.github/codecov.yml
+++ b/.github/codecov.yml
@@ -5,7 +5,7 @@ codecov:
comment: off
ignore:
- "Doc/**/*"
- - "Misc/*"
+ - "Misc/**/*"
- "Mac/**/*"
- "PC/**/*"
- "PCbuild/**/*"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000000000..b8ff7ed5109239
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,187 @@
+name: Tests
+
+# bpo-40548: "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:
+ pull_request:
+ branches:
+ - master
+ - 3.8
+ - 3.7
+
+jobs:
+ check_source:
+ name: 'Check for source changes'
+ runs-on: ubuntu-latest
+ outputs:
+ run_tests: ${{ steps.check.outputs.run_tests }}
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 1000
+ - name: Check for source changes
+ id: check
+ run: |
+ if [ -z "$GITHUB_BASE_REF" ]; then
+ echo '::set-output name=run_tests::true'
+ 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)' && echo '::set-output name=run_tests::true' || true
+ fi
+
+ check_abi:
+ name: 'Check if the ABI has changed'
+ runs-on: ubuntu-20.04
+ needs: check_source
+ if: needs.check_source.outputs.run_tests == 'true'
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
+ - name: Install Dependencies
+ run: |
+ sudo ./.github/workflows/posix-deps-apt.sh
+ sudo apt-get install -yq abigail-tools
+ - name: Build CPython
+ env:
+ CFLAGS: -g3 -O0
+ run: |
+ # Build Python with the libpython dynamic library
+ ./configure --enable-shared
+ make -j4
+ - name: Check for changes in the ABI
+ run: make check-abidump
+
+ check_generated_files:
+ name: 'Check if generated files are up to date'
+ runs-on: ubuntu-latest
+ needs: check_source
+ if: needs.check_source.outputs.run_tests == 'true'
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
+ - name: Install Dependencies
+ run: sudo ./.github/workflows/posix-deps-apt.sh
+ - name: Build CPython
+ run: |
+ ./configure --with-pydebug
+ make -j4 regen-all
+ - name: Check for changes
+ run: |
+ changes=$(git status --porcelain)
+ # Check for changes in regenerated files
+ if ! test -z "$changes"
+ then
+ echo "Generated files not up to date. Perhaps you forgot to run make regen-all ;)"
+ echo "$changes"
+ exit 1
+ fi
+ - name: Check exported libpython symbols
+ run: make smelly
+
+ build_win32:
+ name: 'Windows (x86)'
+ runs-on: windows-2019
+ needs: check_source
+ if: needs.check_source.outputs.run_tests == 'true'
+ steps:
+ - uses: actions/checkout@v2
+ - name: Build CPython
+ run: .\PCbuild\build.bat -e -p Win32
+ - name: Display build info
+ run: .\python.bat -m test.pythoninfo
+ - name: Tests
+ run: .\PCbuild\rt.bat -p Win32 -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
+
+ build_win_amd64:
+ name: 'Windows (x64)'
+ runs-on: windows-2019
+ needs: check_source
+ if: needs.check_source.outputs.run_tests == 'true'
+ steps:
+ - uses: actions/checkout@v2
+ - name: Build CPython
+ run: .\PCbuild\build.bat -e -p x64
+ - name: Display build info
+ run: .\python.bat -m test.pythoninfo
+ - name: Tests
+ run: .\PCbuild\rt.bat -p x64 -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
+
+ build_macos:
+ name: 'macOS'
+ runs-on: macos-latest
+ needs: check_source
+ if: needs.check_source.outputs.run_tests == 'true'
+ env:
+ HOMEBREW_NO_ANALYTICS: 1
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
+ steps:
+ - uses: actions/checkout@v2
+ - name: Configure CPython
+ run: |
+ brew install pkg-config openssl@1.1 xz gdbm tcl-tk
+ brew install zlib bzip2 ncurses readline sqlite
+ SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk \
+ CC=clang \
+ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include \
+ -I$(brew --prefix zlib)/include -I$(brew --prefix bzip2)/include \
+ -I$(brew --prefix ncurses)/include -I$(brew --prefix readline)/include \
+ -I$(brew --prefix sqlite)/include" \
+ LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib \
+ -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib \
+ -L$(brew --prefix ncurses)/lib -L$(brew --prefix readline)/lib \
+ -L$(brew --prefix sqlite)/lib" \
+ ./configure --prefix=/opt/python-dev \
+ --with-pydebug \
+ --with-openssl="$(brew --prefix openssl@1.1)" \
+ --with-tcltk-libs="$(pkg-config --libs tk)" \
+ --with-tcltk-includes="$(pkg-config --cflags tk)"
+ - name: Build CPython
+ run: make -j4
+ - name: Display build info
+ run: make pythoninfo
+ - name: Tests
+ run: make buildbottest TESTOPTS="-j4 -uall,-cpu"
+
+ build_ubuntu:
+ name: 'Ubuntu'
+ runs-on: ubuntu-20.04
+ needs: check_source
+ if: needs.check_source.outputs.run_tests == 'true'
+ env:
+ OPENSSL_VER: 1.1.1u
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: sudo ./.github/workflows/posix-deps-apt.sh
+ - name: 'Restore OpenSSL build'
+ id: cache-openssl
+ uses: actions/cache@v2.1.3
+ with:
+ path: ./multissl/openssl/${{ env.OPENSSL_VER }}
+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
+ - name: Install OpenSSL
+ if: steps.cache-openssl.outputs.cache-hit != 'true'
+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $PWD/multissl --openssl $OPENSSL_VER --system Linux
+ - name: Configure CPython
+ run: ./configure --with-pydebug --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER
+ - name: Build CPython
+ run: make -j4
+ - name: Display build info
+ run: make pythoninfo
+ - name: Tests
+ run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml
new file mode 100644
index 00000000000000..769b3d012e9407
--- /dev/null
+++ b/.github/workflows/build_msi.yml
@@ -0,0 +1,34 @@
+name: TestsMSI
+
+on:
+ push:
+ branches:
+ - master
+ - 3.8
+ - 3.7
+ paths:
+ - 'Tools/msi/**'
+ pull_request:
+ branches:
+ - master
+ - 3.8
+ - 3.7
+ paths:
+ - 'Tools/msi/**'
+
+jobs:
+ build_win32:
+ name: 'Windows (x86) Installer'
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Build CPython installer
+ run: .\Tools\msi\build.bat -x86
+
+ build_win_amd64:
+ name: 'Windows (x64) Installer'
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Build CPython installer
+ run: .\Tools\msi\build.bat -x64
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 00000000000000..762cdb5ab2188a
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,89 @@
+name: Coverage
+
+on:
+ push:
+ branches:
+ - master
+ - 3.8
+ - 3.7
+ paths-ignore:
+ - 'Doc/**'
+ - 'Misc/**'
+ #pull_request:
+ # branches:
+ # - master
+ # - 3.8
+ # - 3.7
+ # paths-ignore:
+ # - 'Doc/**'
+ # - 'Misc/**'
+
+jobs:
+ coverage_ubuntu:
+ name: 'Ubuntu (Coverage)'
+ runs-on: ubuntu-latest
+ env:
+ OPENSSL_VER: 1.1.1n
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: sudo ./.github/workflows/posix-deps-apt.sh
+ - name: 'Restore OpenSSL build'
+ id: cache-openssl
+ uses: actions/cache@v2.1.3
+ with:
+ path: ./multissl/openssl/${{ env.OPENSSL_VER }}
+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
+ - name: Install OpenSSL
+ if: steps.cache-openssl.outputs.cache-hit != 'true'
+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $PWD/multissl --openssl $OPENSSL_VER --system Linux
+ - name: Configure CPython
+ run: ./configure --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER
+ - name: Build CPython
+ run: make -j4
+ - name: Display build info
+ run: make pythoninfo
+ - name: 'Coverage Preparation'
+ run: |
+ ./python -m venv .venv
+ source ./.venv/bin/activate
+ python -m pip install -U coverage
+ python -m test.pythoninfo
+ - name: 'Tests with coverage'
+ run: >
+ source ./.venv/bin/activate &&
+ xvfb-run python -m coverage
+ run --branch --pylib
+ -m test
+ --fail-env-changed
+ -uall,-cpu
+ -x test_multiprocessing_fork
+ -x test_multiprocessing_forkserver
+ -x test_multiprocessing_spawn
+ -x test_concurrent_futures
+ || true
+ - name: 'Publish code coverage results'
+ run: |
+ source ./.venv/bin/activate
+ bash <(curl -s https://codecov.io/bash)
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+
+ c_coverage_ubuntu:
+ name: 'Ubuntu (C Coverage)'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: sudo ./.github/workflows/posix-deps-apt.sh
+ - name: Configure CPython
+ run: ./configure
+ - name: 'Build CPython and measure coverage'
+ run: xvfb-run make -j4 coverage-report
+ - name: 'Publish code coverage results'
+ if: always()
+ run: |
+ make pythoninfo
+ bash <(curl -s https://codecov.io/bash)
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml
new file mode 100644
index 00000000000000..6dba417e93e640
--- /dev/null
+++ b/.github/workflows/doc.yml
@@ -0,0 +1,40 @@
+name: Docs
+
+on:
+ #push:
+ # branches:
+ # - master
+ # - 3.8
+ # - 3.7
+ # paths:
+ # - 'Doc/**'
+ pull_request:
+ branches:
+ - master
+ - 3.8
+ - 3.7
+ paths:
+ - 'Doc/**'
+ - 'Misc/**'
+
+jobs:
+ build_doc:
+ name: 'Docs'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: 'Install Dependencies'
+ run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican
+ - name: 'Configure CPython'
+ run: ./configure --with-pydebug
+ - name: 'Build CPython'
+ run: make -j4
+ - name: 'Install build dependencies'
+ run: make -C Doc/ PYTHON=../python venv
+ - name: 'Build documentation'
+ run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W -j4" suspicious html
+ - name: 'Upload'
+ uses: actions/upload-artifact@v1
+ with:
+ name: doc-html
+ path: Doc/build/html
diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh
new file mode 100755
index 00000000000000..2b879d32f8150d
--- /dev/null
+++ b/.github/workflows/posix-deps-apt.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+apt-get update
+
+apt-get -yq install \
+ build-essential \
+ zlib1g-dev \
+ libbz2-dev \
+ liblzma-dev \
+ libncurses5-dev \
+ libreadline6-dev \
+ libsqlite3-dev \
+ libssl-dev \
+ libgdbm-dev \
+ tk-dev \
+ lzma \
+ lzma-dev \
+ liblzma-dev \
+ libffi-dev \
+ uuid-dev \
+ xvfb \
+ lcov
diff --git a/.github/workflows/verify-ensurepip-wheels.yml b/.github/workflows/verify-ensurepip-wheels.yml
new file mode 100644
index 00000000000000..61e3d1adf534d5
--- /dev/null
+++ b/.github/workflows/verify-ensurepip-wheels.yml
@@ -0,0 +1,28 @@
+name: Verify bundled pip and setuptools
+
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - 'Lib/ensurepip/_bundled/**'
+ - '.github/workflows/verify-ensurepip-wheels.yml'
+ - 'Tools/scripts/verify_ensurepip_wheels.py'
+ pull_request:
+ paths:
+ - 'Lib/ensurepip/_bundled/**'
+ - '.github/workflows/verify-ensurepip-wheels.yml'
+ - 'Tools/scripts/verify_ensurepip_wheels.py'
+
+permissions:
+ contents: read
+
+jobs:
+ verify:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: '3'
+ - name: Compare checksums of bundled pip and setuptools to ones published on PyPI
+ run: ./Tools/scripts/verify_ensurepip_wheels.py
diff --git a/.gitignore b/.gitignore
index 05fb6cba0875a1..6ebf6247f67284 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,14 +1,8 @@
-# added for local development
-.buildaix/
-Modules/python.exp
-buildaix/
-installp/
-.gitignore
-
# Two-trick pony for OSX and other case insensitive file systems:
# Ignore ./python binary on Unix but still look into ./Python/ directory.
/python
!/Python/
+
*.cover
*.iml
*.o
@@ -33,7 +27,8 @@ Include/pydtrace_probes.h
Lib/distutils/command/*.pdb
Lib/lib2to3/*.pickle
Lib/test/data/*
-Makefile
+!Lib/test/data/README
+/Makefile
Makefile.pre
Misc/python.pc
Misc/python-config.sh
@@ -83,6 +78,7 @@ config.log
config.status
config.status.lineno
core
+!Tools/msi/core/
db_home
.hg/
.idea/
@@ -93,7 +89,7 @@ libpython*.dylib
libpython*.dll
platform
pybuilddir.txt
-pyconfig.h
+/pyconfig.h
python-config
python-config.py
python.bat
@@ -113,3 +109,4 @@ Tools/ssl/amd64
Tools/ssl/win32
.vs/
.vscode/
+gmon.out
diff --git a/.hgeol b/.hgeol
deleted file mode 100644
index eb19a6c88d28d0..00000000000000
--- a/.hgeol
+++ /dev/null
@@ -1,58 +0,0 @@
-[patterns]
-
-# Non human-editable files are binary
-
-**.dsp = BIN
-**.dsw = BIN
-**.mk = BIN
-**.sln = BIN
-**.vcproj = BIN
-**.vsprops = BIN
-
-**.aif = BIN
-**.aifc = BIN
-**.aiff = BIN
-**.au = BIN
-**.bmp = BIN
-**.db = BIN
-**.exe = BIN
-**.icns = BIN
-**.gif = BIN
-**.ico = BIN
-**.info = BIN
-**.jpg = BIN
-**.pck = BIN
-**.png = BIN
-**.psd = BIN
-**.tar = BIN
-**.wav = BIN
-**.whl = BIN
-**.xar = BIN
-**.zip = BIN
-
-Lib/test/cjkencodings/* = BIN
-Lib/test/decimaltestdata/*.decTest = BIN
-Lib/test/sndhdrdata/sndhdr.* = BIN
-Lib/test/test_email/data/msg_26.txt = BIN
-Lib/test/xmltestdata/* = BIN
-
-Lib/venv/scripts/nt/* = BIN
-
-Lib/test/coding20731.py = BIN
-
-# Windows only zlib upstream file
-Modules/zlib/zlib.map = CRLF
-
-# Windows batch files work best with CRLF, there can be subtle problems with LF
-**.bat = CRLF
-
-# The Windows readme is likely to be read in Notepad, so make it readable
-PCbuild/readme.txt = CRLF
-
-# All other files (which presumably are human-editable) are "native".
-# This must be the last rule!
-
-** = native
-
-[repository]
-native = LF
diff --git a/.hgignore b/.hgignore
deleted file mode 100644
index 68c607f2e8d420..00000000000000
--- a/.hgignore
+++ /dev/null
@@ -1,106 +0,0 @@
-.gdb_history
-.purify
-.svn/
-^.idea/
-^.vscode/
-.DS_Store
-Makefile$
-Makefile.pre$
-TAGS$
-autom4te.cache$
-^build/
-^Doc/build/
-^Doc/venv/
-buildno$
-config.cache
-config.log
-config.status
-config.status.lineno
-db_home
-platform$
-pyconfig.h$
-python$
-python.bat$
-python.exe$
-python-config$
-python-config.py$
-reflog.txt$
-tags$
-Misc/python.pc
-Misc/python-config.sh$
-Modules/Setup$
-Modules/Setup.config
-Modules/Setup.local
-Modules/config.c
-Modules/ld_so_aix$
-^lcov-report/
-^core
-^python-gdb.py
-^python.exe-gdb.py
-^pybuilddir.txt
-
-syntax: glob
-libpython*.a
-libpython*.so*
-libpython*.dylib
-libpython*.dll
-*.swp
-*.o
-*.pyc
-*.pyo
-*.pyd
-*.cover
-*~
-*.gc??
-*.profclang?
-*.profraw
-*.dyn
-Include/pydtrace_probes.h
-Lib/distutils/command/*.pdb
-Lib/lib2to3/*.pickle
-Lib/test/data/*
-Misc/*.wpu
-PC/python_nt*.h
-PC/pythonnt_rc*.h
-PC/*/*.exe
-PC/*/*.exp
-PC/*/*.lib
-PC/*/*.bsc
-PC/*/*.dll
-PC/*/*.pdb
-PC/*/*.user
-PC/*/*.ncb
-PC/*/*.suo
-PC/*/Win32-temp-*
-PC/*/x64-temp-*
-PC/*/amd64
-PCbuild/*.user
-PCbuild/*.suo
-PCbuild/*.*sdf
-PCbuild/*-pgi
-PCbuild/*-pgo
-PCbuild/.vs
-PCbuild/amd64
-PCbuild/obj
-PCbuild/win32
-Tools/unicode/build/
-Tools/unicode/MAPPINGS/
-BuildLog.htm
-__pycache__
-Parser/pgen{,.exe}
-Programs/_freeze_importlib{,.exe}
-Programs/_testembed{,.exe}
-.coverage
-coverage/
-externals/
-htmlcov/
-*.gcda
-*.gcno
-*.gcov
-ipch/
-coverage.info
-Tools/msi/obj
-Tools/ssl/amd64
-Tools/ssl/win32
-.vs/
-.vscode/
diff --git a/.hgtags b/.hgtags
deleted file mode 100644
index 8f51c2ced49aed..00000000000000
--- a/.hgtags
+++ /dev/null
@@ -1,182 +0,0 @@
-64cc5439e10a6fdf984effaf0141e94fa4cc1004 v0.9.8
-78a7ed6953025e7ecdde9585099b01a6ae40b76a v0.9.9
-b15b8cc9b8d10e0352a0b8b7e8d51fa309db6df3 v1.0.1
-0326b5d61445ee3a8d3de28119f9652cb72d2e3f v1.0.2
-832615ec07646e310c85316b8ba6bc9b17ad3547 v1.1
-9895475d18c7b5f32adaf78f71886ae041e4d10c v1.1.1
-16eb4c51ee97169046340998e850a63c65225b0a v1.2b1
-b45c688756d04fb84d4a0d518fc3d7e3cb25fa8d v1.2b2
-9e82daf7605bad7976a9abc997cb5e0abe434078 v1.2b3
-065e31cf5862e27521cf5725b003aed211f091b2 v1.2b4
-e72257e655454d569468da8b1189e0ec336f3536 v1.2
-e63d83f8275853aaaa3d1972cb86564505e65583 v1.3b1
-7d743c865a9aa6bde8b603e32e0542031bba3c33 v1.3
-4fc85c82cc222554ae6b9c0b87776ed5f2b70c6e v1.4b1
-129f1299d4e97e884bbbbdd00baf101d178973e6 v1.4b2
-44a82ac654a4175569deed8e8a94b0cc8edee08d v1.4b3
-db49494c93dc73de06d5721c74eab533a947a92c v1.4
-062aed8a4ce2c91c81b80e29f02faff1cf5a761b v1.5a1
-c9498ac988372575cf7028b86395b900c9b0a840 v1.5a2
-dc5c968ec992aab3d40a7189df0c443d1c7a1a68 v1.5a3
-746654a0af680c7d9b814b210a026eb91bec9533 v1.5a4
-8ff58b5730f06be08fbbdc2bf592226f7a736201 v1.5b1
-eb78658d819fb0af09a8e6f9bedcb670805ed5f6 v1.5b2
-84461011a1a0ab402e352f06748f29fb5b5559e5 v1.5
-44aba4d26b01fbae0403efe654f9fd0347606732 v1.5.1
-fed63ccbe6dc3ac663bfe97a2f7006b1b28568f9 v1.5.2a1
-21d71f2e27248a0f4e393d0fc321ecf9b89321d2 v1.5.2a2
-f08c7a2a56f80741f5f192fd0ebe0b0967a203cf v1.5.2b1
-8fe7ec4b4fc1518fcac89e6bf674fbbce16150a9 v1.5.2b2
-39fb0dcc83dc375c1565ba65dbce0ed59b1359c9 v1.5.2c1
-61c91c7f101bab3149adfcd5646ae40e048de712 v1.5.2
-605eb9326ffe1fd1e43f40e2338d6652ab449fdf v1.6a1
-011bee8fd9f7f4da457ec71596484fb0882c0614 v1.6a2
-35c4fc1414a59888614b9be784a25f233ba67984 v2.0b1
-55bba197d4870cdae62aeca00e20240a756b84f8 v2.0b2
-e276329cce036a5f9e9d3451256dca5984e543dc v2.0c1
-2fa4e35083e02342ca014bf5bfba46aecb816c31 v2.0
-b60831eeab5a06dd3c5e8297a99e39297aa8794b v2.1a1
-b382f1f07ec6b2c95551658b30c6139eeb32077a v2.1a2
-d0c830db5e68edd4aaa3401216e610c9ff145826 v2.1b1
-b59a536ae1ef3774fd85c17f623e8926b7b6c095 v2.1b2
-d611276e9ad53b5d32d1e8065e1d811c32f7d96f v2.1c1
-ff065e674af6c9ab895bd9eff7d9e9039a376c7d v2.1c2
-020e95d8180d7943fe54701e1db0a7d7d87e2b1e v2.1
-08796a137f1ada2462f7a3177306df5f67a767e1 v2.2a3
-d054c29647f90bccb8345bd779bca1eecf2dd7f2 v2.3c1
-fce5c9e9abc722394cb2e909b7e2a39080d4448e v2.3c2
-92ca658fd420095b6284c9ce6e9082a80285ec9c v2.4a1
-055fc6955f3c6522bfeb7ed4c671c97d5baaaac2 v2.4a2
-186b72550e53533ef6175f6411f932c1298193d7 v2.4a3
-53cff04283855adf88ed0c0fd3698827ca843637 v2.4b1
-7e387a9dcc79954a77695adef8b593da35be1214 v2.4b2
-ff80d8bbef6e13426c8a85d7f9d837b8f8f89834 v2.4c1
-f31e18d313c7a4fc66914b2d27e130a0f72c0b69 v2.4
-cd3f783cd08a16781e236c0b9cb5717d1d995fa9 v3.0a1
-65e82140e281bf26f2e22eda05a7f9956c420f8b v3.0a2
-df15827f34881b9af0936350813ced5c123c8230 v3.0a3
-15f773f7300e372c56a21d59fe49ca26955a6477 v3.0a4
-e35935475153377d6727d64e6c52f72c3b84015b v3.0a5
-a335c4d643b1cfe14197a9ef195c9b2804f608fc v3.0b1
-16ec4bb14a68ea428acf09ebf0c92981da2646f3 v3.0b2
-509e30a7968e01be329ec121540b3e755fc4e566 v3.0b3
-507ede9c7f7f475dfafbd4a52c22d767d10a2bc0 v3.0rc1
-8fae465a39627b590385462e6095eb63af45240a v3.0rc2
-e83a60c69d53f5551a306e77a6d38e9b11485496 v3.0rc3
-bc1ce368986e45b1faf96f93995df46bcd75e7b8 v3.1a1
-ee430e5075db2adf8124e6b94916a89ca41d3171 v3.1a2
-b63020797f9678adaf4d2c3e26574a9eef2ef028 v3.1b1
-4353fd0843cb31b356adc50f93d220e2e7255ef2 v3.1rc1
-0b87e438e1b53e3f812cad963a7fdb65d198ba2f v3.1rc2
-a69a031ac1402dede8b1ef80096436bca6d371f3 v3.1
-35efb1054ec6ceca72017a587263cb6a9257340b v3.1.1rc1
-8b9c0f573ab29c41c6c5fdcca82a1fe0ff5355af v3.1.1
-149b8b87514d10416b598884db5f74651f625b38 v3.1.2rc1
-960efa327c5d9c18df995437b0ac550cb89c9f85 v3.1.2
-d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1
-a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3
-32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1
-c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4
-ee26aca3219cf4bb0b93352e83edcc9cb28c7802 v3.1.5rc1
-75db2bc69fc9a3e4801e94e3e19801cb096208d8 v3.1.5rc2
-7395330e495ec3316862ca1f6ce0aaf7bdf6785b v3.1.5
-b37b7834757492d009b99cf0ca4d42d2153d7fac v3.2a1
-56d4373cecb73c8b45126ba7b045b3c7b3f94b0b v3.2a2
-da012d9a2c23d144e399d2e01a55b8a83ad94573 v3.2a3
-d92a5b850f5e56808bedc01723906ed64c5e6e2e v3.2a4
-b635cea94195780c8716e236479af319bcc26253 v3.2b1
-e3af5f3a7904c0d5343ec9633ea66e7acfd23a66 v3.2b2
-865d5b24bf28ca41b536befc326407c03e74a4d5 v3.2rc1
-acf3e24dd0d0dfd1e20c907d696d3da965a8f56f v3.2rc2
-18c1f52896501c7ee13b038454a39acb45a87979 v3.2rc3
-a222a015e28d8ae9af3899258dc6c15c3d40add0 v3.2
-8ffac2337a3323323d02153ac919fd1483176652 v3.2.1b1
-cfa9364997c7f2e67b9cbb45c3a5fa3bba4e4999 v3.2.1rc1
-5df549718fb4841ff521fe051f6b54f290fad5d8 v3.2.1rc2
-ac1f7e5c05104d557d5acd922e95625ba5d1fe10 v3.2.1
-c860feaa348d663e598986894ee4680480577e15 v3.2.2rc1
-137e45f15c0bd262c9ad4c032d97425bc0589456 v3.2.2
-7085403daf439adb3f9e70ef13f6bedb1c447376 v3.2.3rc1
-428f05cb7277e1d42bb9dd8d1af6b6270ebc6112 v3.2.3rc2
-3d0686d90f55a78f96d9403da2c52dc2411419d0 v3.2.3
-b2cb7bc1edb8493c0a78f9331eae3e8fba6a881d v3.2.4rc1
-1e10bdeabe3de02f038a63c001911561ac1d13a7 v3.2.4
-cef745775b6583446572cffad704100983db2bea v3.2.5
-51382a5598ec96119cb84594572901c9c964dc3c v3.2.6rc1
-0bd5f4f14de965ca8e44c6e3965fee106176cfc4 v3.2.6
-f1a9a6505731714f0e157453ff850e3b71615c45 v3.3.0a1
-2f69db52d6de306cdaef0a0cc00cc823fb350b01 v3.3.0a2
-0b53b70a40a00013505eb35e3660057b62be77be v3.3.0a3
-7c51388a3aa7ce76a8541bbbdfc05d2d259a162c v3.3.0a4
-e15c554cd43eb23bc0a528a4e8741da9bbec9607 v3.3.0b1
-4972a8f1b2aa3d7cdd64dc96aa7fa112fe1ea343 v3.3.0b2
-8bb5c7bc46ba43804480f3e328e1fa956672c885 v3.3.0rc1
-88a0792e8ba3e4916b24c7e7a522c277d326d66e v3.3.0rc2
-c191d21cefafb3832c45570e84854e309aa62eaa v3.3.0rc3
-bd8afb90ebf28ba4edc901d4a235f75e7bbc79fd v3.3.0
-92c2cfb924055ce68c4f78f836dcfe688437ceb8 v3.3.1rc1
-d9893d13c6289aa03d33559ec67f97dcbf5c9e3c v3.3.1
-d047928ae3f6314a13b6137051315453d0ae89b6 v3.3.2
-fd53c500f8b80f54f3ecedec9da2e8c7e52a6888 v3.3.3rc1
-d32442c0e60dfbd71234e807d3d1dedd227495a9 v3.3.3rc2
-c3896275c0f61b2510a6c7e6c458a750359a91b8 v3.3.3
-fa92f5f940c6c0d839d7f0611e4b717606504a3c v3.3.4rc1
-7ff62415e4263c432c8acf6e424224209211eadb v3.3.4
-9ec811df548ed154a9bf9815383a916d6df31b98 v3.3.5rc1
-ca5635efe090f78806188ac2758f9948596aa8b2 v3.3.5rc2
-62cf4e77f78564714e7ea3d4bf1479ca1fbd0758 v3.3.5
-51317c9786f54267975abf2e9c502e6aaaa4a249 v3.3.6rc1
-971fec30da1fc5bf2b9fb28e09812a5127014211 v3.3.6
-46535f65e7f3bcdcf176f36d34bc1fed719ffd2b v3.4.0a1
-9265a2168e2cb2a84785d8717792acc661e6b692 v3.4.0a2
-dd9cdf90a5073510877e9dd5112f8e6cf20d5e89 v3.4.0a3
-e245b0d7209bb6d0e19316e1e2af1aa9c2139104 v3.4.0a4
-3405dc9a6afaa0a06dd1f6f182ec5c998dce6f5f v3.4.0b1
-ba32913eb13ec545a46dd0ce18035b6c416f0d78 v3.4.0b2
-a97ce3ecc96af79bd2e1ac66ce48d9138e0ca749 v3.4.0b3
-5e088cea8660677969113741c1313d570d977e02 v3.4.0rc1
-a300712ed38c9a242b736c44e806caea25a6dc05 v3.4.0rc2
-8a81cdab3e9d521daaef989fade94b16455fc3b8 v3.4.0rc3
-04f714765c13824c3bc2835d7b008908862e083a v3.4.0
-c67a19e11a7191baf30f313bf55e2e0b6c6f574e v3.4.1rc1
-c0e311e010fcb5bae8d87ca22051cd0845ea0ca0 v3.4.1
-8711a09513848cfc48c689d983495ee64f4668ca v3.4.2rc1
-ab2c023a9432f16652e89c404bbc84aa91bf55af v3.4.2
-69dd528ca6255a66c37cc5cf680e8357d108b036 v3.4.3rc1
-b4cbecbc0781e89a309d03b60a1f75f8499250e6 v3.4.3
-04f3f725896c6961212c3a12e8ac25be6958f4fa v3.4.4rc1
-737efcadf5a678b184e0fa431aae11276bf06648 v3.4.4
-3631bb4a2490292ebf81d3e947ae36da145da564 v3.4.5rc1
-619b61e505d0e2ccc8516b366e4ddd1971b46a6f v3.4.5
-e199a272ccdac5a8c073d4690f60c13e0b6d86b0 v3.4.6rc1
-b662f47769213f23325144b80782c05764d0f053 v3.4.6
-5d4b6a57d5fd7564bf73f3db0e46fe5eeb00bcd8 v3.5.0a1
-0337bd7ebcb6559d69679bc7025059ad1ce4f432 v3.5.0a2
-82656e28b5e5c4ae48d8dd8b5f0d7968908a82b6 v3.5.0a3
-413e0e0004f4f954331cb8122aa55fe208984955 v3.5.0a4
-071fefbb5e3db770c6c19fba9994699f121b1cea v3.5.0b1
-7a088af5615bf04024e9912068f4bd8f43ed3917 v3.5.0b2
-0035fcd9b9243ae52c2e830204fd9c1f7d528534 v3.5.0b3
-c0d64105463581f85d0e368e8d6e59b7fd8f12b1 v3.5.0b4
-1a58b1227501e046eee13d90f113417b60843301 v3.5.0rc1
-cc15d736d860303b9da90d43cd32db39bab048df v3.5.0rc2
-66ed52375df802f9d0a34480daaa8ce79fc41313 v3.5.0rc3
-2d033fedfa7f1e325fd14ccdaa9cb42155da206f v3.5.0rc4
-374f501f4567b7595f2ad7798aa09afa2456bb28 v3.5.0
-948ef16a69513ba1ff15c9d7d0b012b949df4c80 v3.5.1rc1
-37a07cee5969e6d3672583187a73cf636ff28e1b v3.5.1
-68feec6488b26327a85a634605dd28eca4daa5f1 v3.5.2rc1
-4def2a2901a5618ea45bcc8f2a1411ef33af18ad v3.5.2
-de530d7f21c0398bb2a2b67716e0638e5fadf727 v3.5.3rc1
-1880cb95a742cd001c67677de5c4efeab169416c v3.5.3
-5896da372fb044e38595fb74495de1e1e7c8fb3c v3.6.0a1
-37889342355223e2fc1438de3dc7ffcd625c60f7 v3.6.0a2
-f3edf13dc339b8942ae6b309771ab197dd8ce6fa v3.6.0a3
-017cf260936b444788c9b671d195b7bfd83dbd25 v3.6.0a4
-5b0ca4ed5e2f0669d76ece7ef975c544580f12b4 v3.6.0b1
-b9fadc7d1c3f9c3c77f32f35afbe1a1cc38070e6 v3.6.0b2
-8345e066c0ed713c3e510cbc8fafc1c38d6d306b v3.6.0b3
-18496abdb3d5c2730a659b747a89261b2219fecf v3.6.0b4
-29a273eee9a523ee178f6a66c4ac9d317c8fc84f v3.6.0rc1
-800a67f7806de45a7abd5273359e704bf147c079 v3.6.0rc2
-41df79263a11f2429d1dd0cfe12553de3dcb5508 v3.6.0
diff --git a/.travis.yml b/.travis.yml
index d7387e5f9831b2..3615ec03b0465f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,30 +1,32 @@
language: c
-dist: trusty
-sudo: false
-group: beta
+dist: xenial
# To cache doc-building dependencies and C compiler output.
cache:
- - pip
- - ccache
- - directories:
- - $HOME/multissl
+ - pip
+ - ccache
+ - directories:
+ - $HOME/multissl
env:
global:
- - OPENSSL=1.1.0g
+ - OPENSSL=1.1.1f
- OPENSSL_DIR="$HOME/multissl/openssl/${OPENSSL}"
- PATH="${OPENSSL_DIR}/bin:$PATH"
- - CFLAGS="-I${OPENSSL_DIR}/include"
+ # Use -O3 because we don't use debugger on Travis-CI
+ - CFLAGS="-I${OPENSSL_DIR}/include -O3"
- LDFLAGS="-L${OPENSSL_DIR}/lib"
# Set rpath with env var instead of -Wl,-rpath linker flag
# OpenSSL ignores LDFLAGS when linking bin/openssl
- LD_RUN_PATH="${OPENSSL_DIR}/lib"
+ # python3.x in PATH may be pyenv shims, not real python.
+ - PYTHON_FOR_REGEN=python3
branches:
only:
- master
- /^\d\.\d$/
+ - buildbot-custom
matrix:
fast_finish: true
@@ -38,6 +40,10 @@ matrix:
# compiler here and the other to run the coverage build. Clang is preferred
# in this instance for its better error messages.
env: TESTING=cpython
+ addons:
+ apt:
+ packages:
+ - xvfb
- os: linux
language: python
# Build the docs against a stable version of Python so code bugs don't hold up doc-related PRs.
@@ -47,79 +53,87 @@ matrix:
- cd Doc
# Sphinx 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.)
- - python -m pip install sphinx~=1.6.1 blurb
+ - python -m pip install sphinx==1.8.2 blurb
script:
- make check suspicious html SPHINXOPTS="-q -W -j4"
- os: linux
language: c
compiler: gcc
env: OPTIONAL=true
+ addons:
+ apt:
+ packages:
+ - xvfb
before_script:
- - |
- if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.rst$)|(^Doc)|(^Misc)'
- then
- echo "Only docs were updated, stopping build process."
- exit
- fi
- python3 Tools/ssl/multissltests.py --steps=library \
- --base-directory ${HOME}/multissl \
- --openssl ${OPENSSL} >/dev/null
- openssl version
- ./configure
- make -s -j4
- # Need a venv that can parse covered code.
- ./python -m venv venv
- ./venv/bin/python -m pip install -U coverage
- ./venv/bin/python -m test.pythoninfo
+ - ./configure
+ - make -s -j4
+ # Need a venv that can parse covered code.
+ - ./python -m venv venv
+ - ./venv/bin/python -m pip install -U coverage
+ - ./venv/bin/python -m test.pythoninfo
script:
# Skip tests that re-run the entire test suite.
- - ./venv/bin/python -m coverage run --pylib -m test --fail-env-changed -uall,-cpu -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn -x test_concurrent_futures
+ - xvfb-run ./venv/bin/python -m coverage run --pylib -m test --fail-env-changed -uall,-cpu -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn -x test_concurrent_futures
after_script: # Probably should be after_success once test suite updated to run under coverage.py.
# Make the `coverage` command available to Codecov w/ a version of Python that can parse all source files.
- source ./venv/bin/activate
- bash <(curl -s https://codecov.io/bash)
-# Travis provides only 2 cores, so don't overdo the parallelism and waste memory.
-before_script:
+
+before_install:
+ - set -e
+ - pyenv global 3.7.1 # If this fails, try pyenv versions
- |
- set -e
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
- files_changed=$(git diff --name-only $TRAVIS_COMMIT_RANGE)
- else
- # Pull requests are slightly complicated because merging the PR commit without
- # rebasing causes it to retain its old commit date. Meaning in history if any
- # commits have been made on master that post-date it, they will be accidentally
- # included in the diff if we use the TRAVIS_COMMIT_RANGE variable.
- files_changed=$(git diff --name-only HEAD $(git merge-base HEAD $TRAVIS_BRANCH))
+ # Check short-circuit conditions
+ if [ "${TESTING}" != "docs" ]
+ then
+ if [ "$TRAVIS_PULL_REQUEST" = "false" ]
+ then
+ echo "Not a PR, doing full build."
+ else
+ # Pull requests are slightly complicated because $TRAVIS_COMMIT_RANGE
+ # may include more changes than desired if the history is convoluted.
+ # Instead, explicitly fetch the base branch and compare against the
+ # merge-base commit.
+ git fetch -q origin +refs/heads/$TRAVIS_BRANCH
+ changes=$(git diff --name-only HEAD $(git merge-base HEAD FETCH_HEAD))
+ echo "Files changed:"
+ echo "$changes"
+ if ! echo "$changes" | grep -qvE '(\.rst$)|(^Doc)|(^Misc)'
+ then
+ echo "Only docs were updated, stopping build process."
+ exit
+ fi
+ fi
fi
- # Prints changed files in this commit to help debug doc-only build issues.
- echo "Files changed: "
- echo $files_changed
-
- if ! echo $files_changed | grep -qvE '(\.rst$)|(^Doc)|(^Misc)'
+install:
+ - |
+ # Install OpenSSL as necessary
+ if [ "${TESTING}" != "docs" ]
then
- echo "Only docs were updated, stopping build process."
- exit
- fi
- if [ "${TESTING}" != "docs" ]; then
# clang complains about unused-parameter a lot, redirect stderr
python3 Tools/ssl/multissltests.py --steps=library \
--base-directory ${HOME}/multissl \
--openssl ${OPENSSL} >/dev/null 2>&1
fi
- openssl version
- ./configure --with-pydebug
- make -j4
- make -j4 regen-all clinic
- changes=`git status --porcelain`
+ - openssl version
+
+# Travis provides only 2 cores, so don't overdo the parallelism and waste memory.
+before_script:
+ - ./configure --with-pydebug
+ - make -j4 regen-all
+ - changes=`git status --porcelain`
+ - |
+ # Check for changes in regenerated files
if ! test -z "$changes"
then
echo "Generated files not up to date"
echo "$changes"
exit 1
fi
- make pythoninfo
+ - make -j4
+ - make pythoninfo
script:
# Using the built Python as patchcheck.py is built around the idea of using
@@ -127,10 +141,10 @@ script:
# should be compared against.
# Only run on Linux as the check only needs to be run once.
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./python Tools/scripts/patchcheck.py --travis $TRAVIS_PULL_REQUEST; fi
- # `-r -w` implicitly provided through `make buildbottest`.
- - make buildbottest TESTOPTS="-j4 -uall,-cpu"
# Check that all symbols exported by libpython start with "Py" or "_Py"
- make smelly
+ # `-r -w` implicitly provided through `make buildbottest`.
+ - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then XVFB_RUN=xvfb-run; fi; $XVFB_RUN make buildbottest TESTOPTS="-j4 -uall,-cpu"
notifications:
email: false
diff --git a/.github/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst
similarity index 100%
rename from .github/CODE_OF_CONDUCT.rst
rename to CODE_OF_CONDUCT.rst
diff --git a/Doc/Makefile b/Doc/Makefile
index 307d1e0e7de10b..1ffa67ac93a115 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -12,7 +12,11 @@ PAPER =
SOURCES =
DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py)
-ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_elements.papersize=$(PAPER) \
+# Internal variables.
+PAPEROPT_a4 = -D latex_elements.papersize=a4paper
+PAPEROPT_letter = -D latex_elements.papersize=letterpaper
+
+ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) \
$(SPHINXOPTS) . build/$(BUILDER) $(SOURCES)
.PHONY: help build html htmlhelp latex text changes linkcheck \
@@ -123,7 +127,8 @@ clean:
venv:
$(PYTHON) -m venv $(VENVDIR)
- $(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb
+ $(VENVDIR)/bin/python3 -m pip install -U pip setuptools
+ $(VENVDIR)/bin/python3 -m pip install -r requirements.txt
@echo "The venv has been created in the $(VENVDIR) directory"
dist:
diff --git a/Doc/README.rst b/Doc/README.rst
index a29d1f3a708a43..9fc39834f8b543 100644
--- a/Doc/README.rst
+++ b/Doc/README.rst
@@ -33,7 +33,7 @@ To get started on UNIX, you can create a virtual environment with the command ::
make venv
That will install all the tools necessary to build the documentation. Assuming
-the virtual environment was created in the ``env`` directory (the default;
+the virtual environment was created in the ``venv`` directory (the default;
configurable with the VENVDIR variable), you can run the following command to
build the HTML output files::
@@ -113,6 +113,15 @@ Then, from the ``Doc`` directory, run ::
where ```` is one of html, text, latex, or htmlhelp (for explanations
see the make targets above).
+Deprecation header
+==================
+
+You can define the ``outdated`` variable in ``html_context`` to show a
+red banner on each page redirecting to the "latest" version.
+
+The link points to the same page on ``/3/``, sadly for the moment the
+language is lost during the process.
+
Contributing
============
diff --git a/Doc/bugs.rst b/Doc/bugs.rst
index 109e9eb202d8ea..f416c5a3db37e4 100644
--- a/Doc/bugs.rst
+++ b/Doc/bugs.rst
@@ -17,7 +17,7 @@ Documentation bugs
If you find a bug in this documentation or would like to propose an improvement,
please submit a bug report on the :ref:`tracker `. If you
-have a suggestion how to fix it, include that as well.
+have a suggestion on how to fix it, include that as well.
If you're short on time, you can also email documentation bug reports to
docs@python.org (behavioral bugs can be sent to python-list@python.org).
@@ -32,38 +32,39 @@ though it may take a while to be processed.
Using the Python issue tracker
==============================
-Bug reports for Python itself should be submitted via the Python Bug Tracker
-(https://bugs.python.org/). The bug tracker offers a Web form which allows
-pertinent information to be entered and submitted to the developers.
+Issue reports for Python itself should be submitted via the GitHub issues
+tracker (https://github.com/python/cpython/issues).
+The GitHub issues tracker offers a web form which allows pertinent information
+to be entered and submitted to the developers.
The first step in filing a report is to determine whether the problem has
already been reported. The advantage in doing so, aside from saving the
-developers time, is that you learn what has been done to fix it; it may be that
+developers' time, is that you learn what has been done to fix it; it may be that
the problem has already been fixed for the next release, or additional
information is needed (in which case you are welcome to provide it if you can!).
-To do this, search the bug database using the search box on the top of the page.
+To do this, search the tracker using the search box at the top of the page.
-If the problem you're reporting is not already in the bug tracker, go back to
-the Python Bug Tracker and log in. If you don't already have a tracker account,
-select the "Register" link or, if you use OpenID, one of the OpenID provider
-logos in the sidebar. It is not possible to submit a bug report anonymously.
+If the problem you're reporting is not already in the list, log in to GitHub.
+If you don't already have a GitHub account, create a new account using the
+"Sign up" link.
+It is not possible to submit a bug report anonymously.
-Being now logged in, you can submit a bug. Select the "Create New" link in the
-sidebar to open the bug reporting form.
+Being now logged in, you can submit an issue.
+Click on the "New issue" button in the top bar to report a new issue.
-The submission form has a number of fields. For the "Title" field, enter a
-*very* short description of the problem; less than ten words is good. In the
-"Type" field, select the type of your problem; also select the "Component" and
-"Versions" to which the bug relates.
+The submission form has two fields, "Title" and "Comment".
+
+For the "Title" field, enter a *very* short description of the problem;
+less than ten words is good.
In the "Comment" field, describe the problem in detail, including what you
expected to happen and what did happen. Be sure to include whether any
extension modules were involved, and what hardware and software platform you
were using (including version information as appropriate).
-Each bug report will be assigned to a developer who will determine what needs to
-be done to correct the problem. You will receive an update each time action is
-taken on the bug.
+Each issue report will be reviewed by a developer who will determine what needs to
+be done to correct the problem. You will receive an update each time an action is
+taken on the issue.
.. seealso::
@@ -72,7 +73,7 @@ taken on the bug.
Article which goes into some detail about how to create a useful bug report.
This describes what kind of information is useful and why it is useful.
- `Bug Writing Guidelines `_
+ `Bug Report Writing Guidelines `_
Information about writing a good bug report. Some of this is specific to the
Mozilla project, but describes general good practices.
@@ -87,6 +88,6 @@ patching Python in the `Python Developer's Guide`_. If you have questions,
the `core-mentorship mailing list`_ is a friendly place to get answers to
any and all questions pertaining to the process of fixing issues in Python.
-.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity
+.. _Documentation bugs: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Adocs
.. _Python Developer's Guide: https://devguide.python.org/
-.. _core-mentorship mailing list: https://mail.python.org/mailman/listinfo/core-mentorship/
+.. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/
diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst
index 25a867f139cc7a..c5e548d2668b2b 100644
--- a/Doc/c-api/allocation.rst
+++ b/Doc/c-api/allocation.rst
@@ -48,7 +48,7 @@ Allocating Objects on the Heap
improving the memory management efficiency.
-.. c:function:: void PyObject_Del(PyObject *op)
+.. c:function:: void PyObject_Del(void *op)
Releases memory allocated to an object using :c:func:`PyObject_New` or
:c:func:`PyObject_NewVar`. This is normally called from the
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index e4b48e66bc2d1c..caa93d63db05b8 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -50,7 +50,7 @@ Unless otherwise stated, buffers are not NUL-terminated.
Some formats require a read-only :term:`bytes-like object`, and set a
pointer instead of a buffer structure. They work by checking that
-the object's :c:member:`PyBufferProcs.bf_releasebuffer` field is *NULL*,
+the object's :c:member:`PyBufferProcs.bf_releasebuffer` field is ``NULL``,
which disallows mutable objects such as :class:`bytearray`.
.. note::
@@ -99,15 +99,15 @@ which disallows mutable objects such as :class:`bytearray`.
``z`` (:class:`str` or ``None``) [const char \*]
Like ``s``, but the Python object may also be ``None``, in which case the C
- pointer is set to *NULL*.
+ pointer is set to ``NULL``.
``z*`` (:class:`str`, :term:`bytes-like object` or ``None``) [Py_buffer]
Like ``s*``, but the Python object may also be ``None``, in which case the
- ``buf`` member of the :c:type:`Py_buffer` structure is set to *NULL*.
+ ``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``.
-``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int]
+``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Like ``s#``, but the Python object may also be ``None``, in which case the C
- pointer is set to *NULL*.
+ pointer is set to ``NULL``.
``y`` (read-only :term:`bytes-like object`) [const char \*]
This format converts a bytes-like object to a C pointer to a character
@@ -124,7 +124,7 @@ which disallows mutable objects such as :class:`bytearray`.
bytes-like objects. **This is the recommended way to accept
binary data.**
-``y#`` (read-only :term:`bytes-like object`) [const char \*, int]
+``y#`` (read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`]
This variant on ``s#`` doesn't accept Unicode objects, only bytes-like
objects.
@@ -151,18 +151,34 @@ which disallows mutable objects such as :class:`bytearray`.
Previously, :exc:`TypeError` was raised when embedded null code points
were encountered in the Python string.
-``u#`` (:class:`str`) [const Py_UNICODE \*, int]
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
+
+``u#`` (:class:`str`) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`]
This variant on ``u`` stores into two C variables, the first one a pointer to a
Unicode data buffer, the second one its length. This variant allows
null code points.
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
+
``Z`` (:class:`str` or ``None``) [const Py_UNICODE \*]
Like ``u``, but the Python object may also be ``None``, in which case the
- :c:type:`Py_UNICODE` pointer is set to *NULL*.
+ :c:type:`Py_UNICODE` pointer is set to ``NULL``.
+
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
-``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int]
+``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`]
Like ``u#``, but the Python object may also be ``None``, in which case the
- :c:type:`Py_UNICODE` pointer is set to *NULL*.
+ :c:type:`Py_UNICODE` pointer is set to ``NULL``.
+
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
``U`` (:class:`str`) [PyObject \*]
Requires that the Python object is a Unicode object, without attempting
@@ -181,7 +197,7 @@ which disallows mutable objects such as :class:`bytearray`.
This format requires two arguments. The first is only used as input, and
must be a :c:type:`const char\*` which points to the name of an encoding as a
- NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used.
+ NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
An exception is raised if the named encoding is not known to Python. The
second argument must be a :c:type:`char\*\*`; the value of the pointer it
references will be set to a buffer with the contents of the argument text.
@@ -197,14 +213,14 @@ which disallows mutable objects such as :class:`bytearray`.
recoding them. Instead, the implementation assumes that the byte string object uses
the encoding passed in as parameter.
-``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length]
+``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length]
This variant on ``s#`` is used for encoding Unicode into a character buffer.
Unlike the ``es`` format, this variant allows input data which contains NUL
characters.
It requires three arguments. The first is only used as input, and must be a
:c:type:`const char\*` which points to the name of an encoding as a
- NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used.
+ NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
An exception is raised if the named encoding is not known to Python. The
second argument must be a :c:type:`char\*\*`; the value of the pointer it
references will be set to a buffer with the contents of the argument text.
@@ -214,12 +230,12 @@ which disallows mutable objects such as :class:`bytearray`.
There are two modes of operation:
- If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of
+ If *\*buffer* points a ``NULL`` pointer, the function will allocate a buffer of
the needed size, copy the encoded data into this buffer and set *\*buffer* to
reference the newly allocated storage. The caller is responsible for calling
:c:func:`PyMem_Free` to free the allocated buffer after usage.
- If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer),
+ If *\*buffer* points to a non-``NULL`` pointer (an already allocated buffer),
:c:func:`PyArg_ParseTuple` will use this location as the buffer and interpret the
initial value of *\*buffer_length* as the buffer size. It will then copy the
encoded data into the buffer and NUL-terminate it. If the buffer is not large
@@ -228,7 +244,7 @@ which disallows mutable objects such as :class:`bytearray`.
In both cases, *\*buffer_length* is set to the length of the encoded data
without the trailing NUL byte.
-``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length]
+``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length]
Same as ``es#`` except that byte string objects are passed through without recoding
them. Instead, the implementation assumes that the byte string object uses the
encoding passed in as parameter.
@@ -301,7 +317,7 @@ Other objects
``O`` (object) [PyObject \*]
Store a Python object (without any conversion) in a C object pointer. The C
program thus receives the actual object that was passed. The object's reference
- count is not increased. The pointer stored is not *NULL*.
+ count is not increased. The pointer stored is not ``NULL``.
``O!`` (object) [*typeobject*, PyObject \*]
Store a Python object in a C object pointer. This is similar to ``O``, but
@@ -329,7 +345,7 @@ Other objects
If the *converter* returns ``Py_CLEANUP_SUPPORTED``, it may get called a
second time if the argument parsing eventually fails, giving the converter a
chance to release any memory that it had already allocated. In this second
- call, the *object* parameter will be NULL; *address* will have the same value
+ call, the *object* parameter will be ``NULL``; *address* will have the same value
as in the original call.
.. versionchanged:: 3.1
@@ -421,7 +437,7 @@ API Functions
Parse the parameters of a function that takes both positional and keyword
parameters into local variables. The *keywords* argument is a
- *NULL*-terminated array of keyword parameter names. Empty names denote
+ ``NULL``-terminated array of keyword parameter names. Empty names denote
:ref:`positional-only parameters `.
Returns true on success; on failure, it returns false and raises the
appropriate exception.
@@ -504,8 +520,8 @@ Building values
Create a new value based on a format string similar to those accepted by the
:c:func:`PyArg_Parse\*` family of functions and a sequence of values. Returns
- the value or *NULL* in the case of an error; an exception will be raised if
- *NULL* is returned.
+ the value or ``NULL`` in the case of an error; an exception will be raised if
+ ``NULL`` is returned.
:c:func:`Py_BuildValue` does not always build a tuple. It builds a tuple only if
its format string contains two or more format units. If the format string is
@@ -531,40 +547,41 @@ Building values
``s`` (:class:`str` or ``None``) [const char \*]
Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'``
- encoding. If the C string pointer is *NULL*, ``None`` is used.
+ encoding. If the C string pointer is ``NULL``, ``None`` is used.
- ``s#`` (:class:`str` or ``None``) [const char \*, int]
+ ``s#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Convert a C string and its length to a Python :class:`str` object using ``'utf-8'``
- encoding. If the C string pointer is *NULL*, the length is ignored and
+ encoding. If the C string pointer is ``NULL``, the length is ignored and
``None`` is returned.
``y`` (:class:`bytes`) [const char \*]
This converts a C string to a Python :class:`bytes` object. If the C
- string pointer is *NULL*, ``None`` is returned.
+ string pointer is ``NULL``, ``None`` is returned.
- ``y#`` (:class:`bytes`) [const char \*, int]
+ ``y#`` (:class:`bytes`) [const char \*, int or :c:type:`Py_ssize_t`]
This converts a C string and its lengths to a Python object. If the C
- string pointer is *NULL*, ``None`` is returned.
+ string pointer is ``NULL``, ``None`` is returned.
``z`` (:class:`str` or ``None``) [const char \*]
Same as ``s``.
- ``z#`` (:class:`str` or ``None``) [const char \*, int]
+ ``z#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Same as ``s#``.
- ``u`` (:class:`str`) [const Py_UNICODE \*]
- Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python
- Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned.
+ ``u`` (:class:`str`) [const wchar_t \*]
+ Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4)
+ data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``,
+ ``None`` is returned.
- ``u#`` (:class:`str`) [const Py_UNICODE \*, int]
- Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python
- Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored
+ ``u#`` (:class:`str`) [const wchar_t \*, int or :c:type:`Py_ssize_t`]
+ Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python
+ Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored
and ``None`` is returned.
``U`` (:class:`str` or ``None``) [const char \*]
Same as ``s``.
- ``U#`` (:class:`str` or ``None``) [const char \*, int]
+ ``U#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Same as ``s#``.
``i`` (:class:`int`) [int]
@@ -619,9 +636,9 @@ Building values
``O`` (object) [PyObject \*]
Pass a Python object untouched (except for its reference count, which is
- incremented by one). If the object passed in is a *NULL* pointer, it is assumed
+ incremented by one). If the object passed in is a ``NULL`` pointer, it is assumed
that this was caused because the call producing the argument found an error and
- set an exception. Therefore, :c:func:`Py_BuildValue` will return *NULL* but won't
+ set an exception. Therefore, :c:func:`Py_BuildValue` will return ``NULL`` but won't
raise an exception. If no exception has been raised yet, :exc:`SystemError` is
set.
@@ -636,7 +653,7 @@ Building values
``O&`` (object) [*converter*, *anything*]
Convert *anything* to a Python object through a *converter* function. The
function is called with *anything* (which should be compatible with :c:type:`void
- \*`) as its argument and should return a "new" Python object, or *NULL* if an
+ \*`) as its argument and should return a "new" Python object, or ``NULL`` if an
error occurred.
``(items)`` (:class:`tuple`) [*matching-items*]
@@ -651,7 +668,7 @@ Building values
respectively.
If there is an error in the format string, the :exc:`SystemError` exception is
- set and *NULL* returned.
+ set and ``NULL`` returned.
.. c:function:: PyObject* Py_VaBuildValue(const char *format, va_list vargs)
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index 8c2de9691f3e1a..74f518bab6cde1 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -102,13 +102,13 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
.. c:member:: void \*obj
A new reference to the exporting object. The reference is owned by
- the consumer and automatically decremented and set to *NULL* by
+ the consumer and automatically decremented and set to ``NULL`` by
:c:func:`PyBuffer_Release`. The field is the equivalent of the return
value of any standard C-API function.
As a special case, for *temporary* buffers that are wrapped by
:c:func:`PyMemoryView_FromBuffer` or :c:func:`PyBuffer_FillInfo`
- this field is *NULL*. In general, exporting objects MUST NOT
+ this field is ``NULL``. In general, exporting objects MUST NOT
use this scheme.
.. c:member:: Py_ssize_t len
@@ -130,25 +130,25 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
.. c:member:: Py_ssize_t itemsize
Item size in bytes of a single element. Same as the value of :func:`struct.calcsize`
- called on non-NULL :c:member:`~Py_buffer.format` values.
+ called on non-``NULL`` :c:member:`~Py_buffer.format` values.
Important exception: If a consumer requests a buffer without the
:c:macro:`PyBUF_FORMAT` flag, :c:member:`~Py_buffer.format` will
- be set to *NULL*, but :c:member:`~Py_buffer.itemsize` still has
+ be set to ``NULL``, but :c:member:`~Py_buffer.itemsize` still has
the value for the original format.
If :c:member:`~Py_buffer.shape` is present, the equality
``product(shape) * itemsize == len`` still holds and the consumer
can use :c:member:`~Py_buffer.itemsize` to navigate the buffer.
- If :c:member:`~Py_buffer.shape` is *NULL* as a result of a :c:macro:`PyBUF_SIMPLE`
+ If :c:member:`~Py_buffer.shape` is ``NULL`` as a result of a :c:macro:`PyBUF_SIMPLE`
or a :c:macro:`PyBUF_WRITABLE` request, the consumer must disregard
:c:member:`~Py_buffer.itemsize` and assume ``itemsize == 1``.
.. c:member:: const char \*format
A *NUL* terminated string in :mod:`struct` module style syntax describing
- the contents of a single item. If this is *NULL*, ``"B"`` (unsigned bytes)
+ the contents of a single item. If this is ``NULL``, ``"B"`` (unsigned bytes)
is assumed.
This field is controlled by the :c:macro:`PyBUF_FORMAT` flag.
@@ -158,7 +158,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
The number of dimensions the memory represents as an n-dimensional array.
If it is ``0``, :c:member:`~Py_buffer.buf` points to a single item representing
a scalar. In this case, :c:member:`~Py_buffer.shape`, :c:member:`~Py_buffer.strides`
- and :c:member:`~Py_buffer.suboffsets` MUST be *NULL*.
+ and :c:member:`~Py_buffer.suboffsets` MUST be ``NULL``.
The macro :c:macro:`PyBUF_MAX_NDIM` limits the maximum number of dimensions
to 64. Exporters MUST respect this limit, consumers of multi-dimensional
@@ -198,8 +198,8 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
indicates that no de-referencing should occur (striding in a contiguous
memory block).
- If all suboffsets are negative (i.e. no de-referencing is needed, then
- this field must be NULL (the default value).
+ If all suboffsets are negative (i.e. no de-referencing is needed), then
+ this field must be ``NULL`` (the default value).
This type of array representation is used by the Python Imaging Library
(PIL). See `complex arrays`_ for further information how to access elements
@@ -248,7 +248,7 @@ readonly, format
.. c:macro:: PyBUF_FORMAT
Controls the :c:member:`~Py_buffer.format` field. If set, this field MUST
- be filled in correctly. Otherwise, this field MUST be *NULL*.
+ be filled in correctly. Otherwise, this field MUST be ``NULL``.
:c:macro:`PyBUF_WRITABLE` can be \|'d to any of the flags in the next section.
@@ -349,14 +349,16 @@ The logical structure of NumPy-style arrays is defined by :c:member:`~Py_buffer.
If ``ndim == 0``, the memory location pointed to by :c:member:`~Py_buffer.buf` is
interpreted as a scalar of size :c:member:`~Py_buffer.itemsize`. In that case,
-both :c:member:`~Py_buffer.shape` and :c:member:`~Py_buffer.strides` are *NULL*.
+both :c:member:`~Py_buffer.shape` and :c:member:`~Py_buffer.strides` are ``NULL``.
-If :c:member:`~Py_buffer.strides` is *NULL*, the array is interpreted as
+If :c:member:`~Py_buffer.strides` is ``NULL``, the array is interpreted as
a standard n-dimensional C-array. Otherwise, the consumer must access an
n-dimensional array as follows:
- ``ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1]``
- ``item = *((typeof(item) *)ptr);``
+.. code-block:: c
+
+ ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1];
+ item = *((typeof(item) *)ptr);
As noted above, :c:member:`~Py_buffer.buf` can point to any location within
@@ -405,7 +407,7 @@ to two ``char x[2][3]`` arrays that can be located anywhere in memory.
Here is a function that returns a pointer to the element in an N-D array
-pointed to by an N-dimensional index when there are both non-NULL strides
+pointed to by an N-dimensional index when there are both non-``NULL`` strides
and suboffsets::
void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
@@ -429,14 +431,14 @@ Buffer-related functions
Return ``1`` if *obj* supports the buffer interface otherwise ``0``. When ``1`` is
returned, it doesn't guarantee that :c:func:`PyObject_GetBuffer` will
- succeed.
+ succeed. This function always succeeds.
.. c:function:: int PyObject_GetBuffer(PyObject *exporter, Py_buffer *view, int flags)
Send a request to *exporter* to fill in *view* as specified by *flags*.
If the exporter cannot provide a buffer of the exact type, it MUST raise
- :c:data:`PyExc_BufferError`, set :c:member:`view->obj` to *NULL* and
+ :c:data:`PyExc_BufferError`, set :c:member:`view->obj` to ``NULL`` and
return ``-1``.
On success, fill in *view*, set :c:member:`view->obj` to a new reference
@@ -470,7 +472,29 @@ Buffer-related functions
Return ``1`` if the memory defined by the *view* is C-style (*order* is
``'C'``) or Fortran-style (*order* is ``'F'``) :term:`contiguous` or either one
- (*order* is ``'A'``). Return ``0`` otherwise.
+ (*order* is ``'A'``). Return ``0`` otherwise. This function always succeeds.
+
+
+.. c:function:: void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
+
+ Get the memory area pointed to by the *indices* inside the given *view*.
+ *indices* must point to an array of ``view->ndim`` indices.
+
+
+.. c:function:: int PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
+
+ Copy contiguous *len* bytes from *buf* to *view*.
+ *fort* can be ``'C'`` or ``'F'`` (for C-style or Fortran-style ordering).
+ ``0`` is returned on success, ``-1`` on error.
+
+
+.. c:function:: int PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
+
+ Copy *len* bytes from *src* to its contiguous representation in *buf*.
+ *order* can be ``'C'`` or ``'F'`` or ``'A'`` (for C-style or Fortran-style
+ ordering or either one). ``0`` is returned on success, ``-1`` on error.
+
+ This function fails if *len* != *src->len*.
.. c:function:: void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, int itemsize, char order)
@@ -492,11 +516,8 @@ Buffer-related functions
On success, set :c:member:`view->obj` to a new reference to *exporter* and
return 0. Otherwise, raise :c:data:`PyExc_BufferError`, set
- :c:member:`view->obj` to *NULL* and return ``-1``;
+ :c:member:`view->obj` to ``NULL`` and return ``-1``;
If this function is used as part of a :ref:`getbufferproc `,
*exporter* MUST be set to the exporting object and *flags* must be passed
- unmodified. Otherwise, *exporter* MUST be NULL.
-
-
-
+ unmodified. Otherwise, *exporter* MUST be ``NULL``.
diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst
index 41b6e3c71be53d..e6872ce0cb288b 100644
--- a/Doc/c-api/bytearray.rst
+++ b/Doc/c-api/bytearray.rst
@@ -48,7 +48,7 @@ Direct API functions
.. 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.
+ failure, ``NULL`` is returned.
.. c:function:: PyObject* PyByteArray_Concat(PyObject *a, PyObject *b)
@@ -58,13 +58,13 @@ Direct API functions
.. c:function:: Py_ssize_t PyByteArray_Size(PyObject *bytearray)
- Return the size of *bytearray* after checking for a *NULL* pointer.
+ Return the size of *bytearray* after checking for a ``NULL`` pointer.
.. c:function:: char* PyByteArray_AsString(PyObject *bytearray)
Return the contents of *bytearray* as a char array after checking for a
- *NULL* pointer. The returned array always has an extra
+ ``NULL`` pointer. The returned array always has an extra
null byte appended.
diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst
index 5b9ebf6b6af5f5..6699e35742f9dc 100644
--- a/Doc/c-api/bytes.rst
+++ b/Doc/c-api/bytes.rst
@@ -37,14 +37,14 @@ called with a non-bytes parameter.
.. c:function:: PyObject* PyBytes_FromString(const char *v)
Return a new bytes object with a copy of the string *v* as value on success,
- and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be
+ and ``NULL`` on failure. The parameter *v* must not be ``NULL``; it will not be
checked.
.. c:function:: PyObject* PyBytes_FromStringAndSize(const char *v, Py_ssize_t len)
Return a new bytes object with a copy of the string *v* as value and length
- *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of
+ *len* on success, and ``NULL`` on failure. If *v* is ``NULL``, the contents of
the bytes object are uninitialized.
@@ -145,7 +145,7 @@ called with a non-bytes parameter.
whether there are any other null bytes. The data must not be
modified in any way, unless the object was just created using
``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If
- *o* is not a bytes object at all, :c:func:`PyBytes_AsString` returns *NULL*
+ *o* is not a bytes object at all, :c:func:`PyBytes_AsString` returns ``NULL``
and raises :exc:`TypeError`.
@@ -159,7 +159,7 @@ called with a non-bytes parameter.
Return the null-terminated contents of the object *obj*
through the output variables *buffer* and *length*.
- If *length* is *NULL*, the bytes object
+ If *length* is ``NULL``, the bytes object
may not contain embedded null bytes;
if it does, the function returns ``-1`` and a :exc:`ValueError` is raised.
@@ -181,7 +181,7 @@ called with a non-bytes parameter.
appended to *bytes*; the caller will own the new reference. The reference to
the old value of *bytes* will be stolen. If the new object cannot be
created, the old reference to *bytes* will still be discarded and the value
- of *\*bytes* will be set to *NULL*; the appropriate exception will be set.
+ of *\*bytes* will be set to ``NULL``; the appropriate exception will be set.
.. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
@@ -201,5 +201,5 @@ called with a non-bytes parameter.
desired. On success, *\*bytes* holds the resized bytes object and ``0`` is
returned; the address in *\*bytes* may differ from its input value. If the
reallocation fails, the original bytes object at *\*bytes* is deallocated,
- *\*bytes* is set to *NULL*, :exc:`MemoryError` is set, and ``-1`` is
+ *\*bytes* is set to ``NULL``, :exc:`MemoryError` is set, and ``-1`` is
returned.
diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst
index b8642d0aba9248..07efb9e10e264b 100644
--- a/Doc/c-api/capsule.rst
+++ b/Doc/c-api/capsule.rst
@@ -9,6 +9,8 @@ Capsules
Refer to :ref:`using-capsules` for more information on using these objects.
+.. versionadded:: 3.1
+
.. c:type:: PyCapsule
@@ -19,6 +21,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
regular import mechanism can be used to access C APIs defined in dynamically
loaded modules.
+
.. c:type:: PyCapsule_Destructor
The type of a destructor callback for a capsule. Defined as::
@@ -37,15 +40,15 @@ Refer to :ref:`using-capsules` for more information on using these objects.
.. c:function:: PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
Create a :c:type:`PyCapsule` encapsulating the *pointer*. The *pointer*
- argument may not be *NULL*.
+ argument may not be ``NULL``.
- On failure, set an exception and return *NULL*.
+ On failure, set an exception and return ``NULL``.
- The *name* string may either be *NULL* or a pointer to a valid C string. If
- non-*NULL*, this string must outlive the capsule. (Though it is permitted to
+ The *name* string may either be ``NULL`` or a pointer to a valid C string. If
+ non-``NULL``, this string must outlive the capsule. (Though it is permitted to
free it inside the *destructor*.)
- If the *destructor* argument is not *NULL*, it will be called with the
+ If the *destructor* argument is not ``NULL``, it will be called with the
capsule as its argument when it is destroyed.
If this capsule will be stored as an attribute of a module, the *name* should
@@ -56,20 +59,20 @@ Refer to :ref:`using-capsules` for more information on using these objects.
.. c:function:: void* PyCapsule_GetPointer(PyObject *capsule, const char *name)
Retrieve the *pointer* stored in the capsule. On failure, set an exception
- and return *NULL*.
+ and return ``NULL``.
The *name* parameter must compare exactly to the name stored in the capsule.
- If the name stored in the capsule is *NULL*, the *name* passed in must also
- be *NULL*. Python uses the C function :c:func:`strcmp` to compare capsule
+ If the name stored in the capsule is ``NULL``, the *name* passed in must also
+ be ``NULL``. Python uses the C function :c:func:`strcmp` to compare capsule
names.
.. c:function:: PyCapsule_Destructor PyCapsule_GetDestructor(PyObject *capsule)
Return the current destructor stored in the capsule. On failure, set an
- exception and return *NULL*.
+ exception and return ``NULL``.
- It is legal for a capsule to have a *NULL* destructor. This makes a *NULL*
+ It is legal for a capsule to have a ``NULL`` destructor. This makes a ``NULL``
return code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or
:c:func:`PyErr_Occurred` to disambiguate.
@@ -77,9 +80,9 @@ Refer to :ref:`using-capsules` for more information on using these objects.
.. c:function:: void* PyCapsule_GetContext(PyObject *capsule)
Return the current context stored in the capsule. On failure, set an
- exception and return *NULL*.
+ exception and return ``NULL``.
- It is legal for a capsule to have a *NULL* context. This makes a *NULL*
+ It is legal for a capsule to have a ``NULL`` context. This makes a ``NULL``
return code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or
:c:func:`PyErr_Occurred` to disambiguate.
@@ -87,9 +90,9 @@ Refer to :ref:`using-capsules` for more information on using these objects.
.. c:function:: const char* PyCapsule_GetName(PyObject *capsule)
Return the current name stored in the capsule. On failure, set an exception
- and return *NULL*.
+ and return ``NULL``.
- It is legal for a capsule to have a *NULL* name. This makes a *NULL* return
+ It is legal for a capsule to have a ``NULL`` name. This makes a ``NULL`` return
code somewhat ambiguous; use :c:func:`PyCapsule_IsValid` or
:c:func:`PyErr_Occurred` to disambiguate.
@@ -104,13 +107,13 @@ Refer to :ref:`using-capsules` for more information on using these objects.
import the module conventionally (using :c:func:`PyImport_ImportModule`).
Return the capsule's internal *pointer* on success. On failure, set an
- exception and return *NULL*. However, if :c:func:`PyCapsule_Import` failed to
- import the module, and *no_block* was true, no exception is set.
+ exception and return ``NULL``.
+
.. c:function:: int PyCapsule_IsValid(PyObject *capsule, const char *name)
Determines whether or not *capsule* is a valid capsule. A valid capsule is
- non-*NULL*, passes :c:func:`PyCapsule_CheckExact`, has a non-*NULL* pointer
+ non-``NULL``, passes :c:func:`PyCapsule_CheckExact`, has a non-``NULL`` pointer
stored in it, and its internal name matches the *name* parameter. (See
:c:func:`PyCapsule_GetPointer` for information on how capsule names are
compared.)
@@ -122,29 +125,33 @@ Refer to :ref:`using-capsules` for more information on using these objects.
Return a nonzero value if the object is valid and matches the name passed in.
Return ``0`` otherwise. This function will not fail.
+
.. c:function:: int PyCapsule_SetContext(PyObject *capsule, void *context)
Set the context pointer inside *capsule* to *context*.
Return ``0`` on success. Return nonzero and set an exception on failure.
+
.. c:function:: int PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor)
Set the destructor inside *capsule* to *destructor*.
Return ``0`` on success. Return nonzero and set an exception on failure.
+
.. c:function:: int PyCapsule_SetName(PyObject *capsule, const char *name)
- Set the name inside *capsule* to *name*. If non-*NULL*, the name must
+ Set the name inside *capsule* to *name*. If non-``NULL``, the name must
outlive the capsule. If the previous *name* stored in the capsule was not
- *NULL*, no attempt is made to free it.
+ ``NULL``, no attempt is made to free it.
Return ``0`` on success. Return nonzero and set an exception on failure.
+
.. c:function:: int PyCapsule_SetPointer(PyObject *capsule, void *pointer)
Set the void pointer inside *capsule* to *pointer*. The pointer may not be
- *NULL*.
+ ``NULL``.
Return ``0`` on success. Return nonzero and set an exception on failure.
diff --git a/Doc/c-api/cell.rst b/Doc/c-api/cell.rst
index 427259cc24d8d8..624dfe8508e7e0 100644
--- a/Doc/c-api/cell.rst
+++ b/Doc/c-api/cell.rst
@@ -27,13 +27,13 @@ Cell objects are not likely to be useful elsewhere.
.. c:function:: int PyCell_Check(ob)
- Return true if *ob* is a cell object; *ob* must not be *NULL*.
+ Return true if *ob* is a cell object; *ob* must not be ``NULL``.
.. c:function:: PyObject* PyCell_New(PyObject *ob)
Create and return a new cell object containing the value *ob*. The parameter may
- be *NULL*.
+ be ``NULL``.
.. c:function:: PyObject* PyCell_Get(PyObject *cell)
@@ -44,19 +44,19 @@ Cell objects are not likely to be useful elsewhere.
.. c:function:: PyObject* PyCell_GET(PyObject *cell)
Return the contents of the cell *cell*, but without checking that *cell* is
- non-*NULL* and a cell object.
+ non-``NULL`` and a cell object.
.. c:function:: int PyCell_Set(PyObject *cell, PyObject *value)
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
+ 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.
.. c:function:: void PyCell_SET(PyObject *cell, PyObject *value)
Sets the value of the cell object *cell* to *value*. No reference counts are
- adjusted, and no checks are made for safety; *cell* must be non-*NULL* and must
+ adjusted, and no checks are made for safety; *cell* must be non-``NULL`` and must
be a cell object.
diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst
index dfe3d436e5f4b7..172dcb326a4bc4 100644
--- a/Doc/c-api/codec.rst
+++ b/Doc/c-api/codec.rst
@@ -13,7 +13,7 @@ Codec registry and support functions
.. c:function:: int PyCodec_KnownEncoding(const char *encoding)
Return ``1`` or ``0`` depending on whether there is a registered codec for
- the given *encoding*.
+ the given *encoding*. This function always succeeds.
.. c:function:: PyObject* PyCodec_Encode(PyObject *object, const char *encoding, const char *errors)
@@ -21,7 +21,7 @@ Codec registry and support functions
*object* is passed through the encoder function found for the given
*encoding* using the error handling method defined by *errors*. *errors* may
- be *NULL* to use the default method defined for the codec. Raises a
+ be ``NULL`` to use the default method defined for the codec. Raises a
:exc:`LookupError` if no encoder can be found.
.. c:function:: PyObject* PyCodec_Decode(PyObject *object, const char *encoding, const char *errors)
@@ -30,7 +30,7 @@ Codec registry and support functions
*object* is passed through the decoder function found for the given
*encoding* using the error handling method defined by *errors*. *errors* may
- be *NULL* to use the default method defined for the codec. Raises a
+ be ``NULL`` to use the default method defined for the codec. Raises a
:exc:`LookupError` if no encoder can be found.
@@ -40,7 +40,7 @@ Codec lookup API
In the following functions, the *encoding* string is looked up converted to all
lower-case characters, which makes encodings looked up through this mechanism
effectively case-insensitive. If no codec is found, a :exc:`KeyError` is set
-and *NULL* returned.
+and ``NULL`` returned.
.. c:function:: PyObject* PyCodec_Encoder(const char *encoding)
@@ -92,7 +92,7 @@ Registry API for Unicode encoding error handlers
.. c:function:: PyObject* PyCodec_LookupError(const char *name)
Lookup the error handling callback function registered under *name*. As a
- special case *NULL* can be passed, in which case the error handling callback
+ special case ``NULL`` can be passed, in which case the error handling callback
for "strict" will be returned.
.. c:function:: PyObject* PyCodec_StrictErrors(PyObject *exc)
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index 47dab81891d38f..b4c1372c2394cc 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -17,8 +17,8 @@ dictionary, use :c:func:`PyDict_Check`. The chapter is structured like the
.. warning::
While the functions described in this chapter carefully check the type of the
- objects which are passed in, many of them do not check for *NULL* being passed
- instead of a valid object. Allowing *NULL* to be passed in can cause memory
+ objects which are passed in, many of them do not check for ``NULL`` being passed
+ instead of a valid object. Allowing ``NULL`` to be passed in can cause memory
access violations and immediate termination of the interpreter.
@@ -113,5 +113,5 @@ Other Objects
capsule.rst
gen.rst
coro.rst
+ contextvars.rst
datetime.rst
-
diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst
new file mode 100644
index 00000000000000..c0532f2d09220d
--- /dev/null
+++ b/Doc/c-api/contextvars.rst
@@ -0,0 +1,144 @@
+.. highlightlang:: c
+
+.. _contextvarsobjects:
+
+Context Variables Objects
+-------------------------
+
+.. _contextvarsobjects_pointertype_change:
+.. versionchanged:: 3.7.1
+
+ .. note::
+
+ In Python 3.7.1 the signatures of all context variables
+ C APIs were **changed** to use :c:type:`PyObject` pointers instead
+ of :c:type:`PyContext`, :c:type:`PyContextVar`, and
+ :c:type:`PyContextToken`, e.g.::
+
+ // in 3.7.0:
+ PyContext *PyContext_New(void);
+
+ // in 3.7.1+:
+ PyObject *PyContext_New(void);
+
+ See :issue:`34762` for more details.
+
+
+.. versionadded:: 3.7
+
+This section details the public C API for the :mod:`contextvars` module.
+
+.. c:type:: PyContext
+
+ The C structure used to represent a :class:`contextvars.Context`
+ object.
+
+.. c:type:: PyContextVar
+
+ The C structure used to represent a :class:`contextvars.ContextVar`
+ object.
+
+.. c:type:: PyContextToken
+
+ The C structure used to represent a :class:`contextvars.Token` object.
+
+.. c:var:: PyTypeObject PyContext_Type
+
+ The type object representing the *context* type.
+
+.. c:var:: PyTypeObject PyContextVar_Type
+
+ The type object representing the *context variable* type.
+
+.. c:var:: PyTypeObject PyContextToken_Type
+
+ The type object representing the *context variable token* type.
+
+
+Type-check macros:
+
+.. c:function:: int PyContext_CheckExact(PyObject *o)
+
+ Return true if *o* is of type :c:data:`PyContext_Type`. *o* must not be
+ ``NULL``. This function always succeeds.
+
+.. c:function:: int PyContextVar_CheckExact(PyObject *o)
+
+ Return true if *o* is of type :c:data:`PyContextVar_Type`. *o* must not be
+ ``NULL``. This function always succeeds.
+
+.. c:function:: int PyContextToken_CheckExact(PyObject *o)
+
+ Return true if *o* is of type :c:data:`PyContextToken_Type`.
+ *o* must not be ``NULL``. This function always succeeds.
+
+
+Context object management functions:
+
+.. c:function:: PyObject *PyContext_New(void)
+
+ Create a new empty context object. Returns ``NULL`` if an error
+ has occurred.
+
+.. c:function:: PyObject *PyContext_Copy(PyObject *ctx)
+
+ Create a shallow copy of the passed *ctx* context object.
+ Returns ``NULL`` if an error has occurred.
+
+.. c:function:: PyObject *PyContext_CopyCurrent(void)
+
+ Create a shallow copy of the current thread context.
+ Returns ``NULL`` if an error has occurred.
+
+.. c:function:: int PyContext_Enter(PyObject *ctx)
+
+ Set *ctx* as the current context for the current thread.
+ Returns ``0`` on success, and ``-1`` on error.
+
+.. c:function:: int PyContext_Exit(PyObject *ctx)
+
+ Deactivate the *ctx* context and restore the previous context as the
+ current context for the current thread. Returns ``0`` on success,
+ and ``-1`` on error.
+
+.. c:function:: int PyContext_ClearFreeList()
+
+ Clear the context variable free list. Return the total number of
+ freed items. This function always succeeds.
+
+
+Context variable functions:
+
+.. c:function:: PyObject *PyContextVar_New(const char *name, PyObject *def)
+
+ Create a new ``ContextVar`` object. The *name* parameter is used
+ for introspection and debug purposes. The *def* parameter may optionally
+ specify the default value for the context variable. If an error has
+ occurred, this function returns ``NULL``.
+
+.. c:function:: int PyContextVar_Get(PyObject *var, PyObject *default_value, PyObject **value)
+
+ Get the value of a context variable. Returns ``-1`` if an error has
+ occurred during lookup, and ``0`` if no error occurred, whether or not
+ a value was found.
+
+ If the context variable was found, *value* will be a pointer to it.
+ If the context variable was *not* found, *value* will point to:
+
+ - *default_value*, if not ``NULL``;
+ - the default value of *var*, if not ``NULL``;
+ - ``NULL``
+
+ If the value was found, the function will create a new reference to it.
+
+.. c:function:: PyObject *PyContextVar_Set(PyObject *var, PyObject *value)
+
+ Set the value of *var* to *value* in the current context. Returns a
+ pointer to a :c:type:`PyObject` object, or ``NULL`` if an error
+ has occurred.
+
+.. c:function:: int PyContextVar_Reset(PyObject *var, PyObject *token)
+
+ Reset the state of the *var* context variable to that it was in before
+ :c:func:`PyContextVar_Set` that returned the *token* was called.
+ This function returns ``0`` on success and ``-1`` on error.
diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst
index 9566d9d792000d..8ea85895a4c41a 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -32,7 +32,7 @@ NULL``.
If the platform doesn't have :c:func:`vsnprintf` and the buffer size needed to
avoid truncation exceeds *size* by more than 512 bytes, Python aborts with a
-*Py_FatalError*.
+:c:func:`Py_FatalError`.
The return value (*rv*) for these functions should be interpreted as follows:
@@ -60,7 +60,7 @@ The following functions provide locale-independent string to number conversions.
The conversion is independent of the current locale.
If ``endptr`` is ``NULL``, convert the whole string. Raise
- ValueError and return ``-1.0`` if the string is not a valid
+ :exc:`ValueError` and return ``-1.0`` if the string is not a valid
representation of a floating-point number.
If endptr is not ``NULL``, convert as much of the string as
@@ -95,25 +95,25 @@ The following functions provide locale-independent string to number conversions.
must be 0 and is ignored. The ``'r'`` format code specifies the
standard :func:`repr` format.
- *flags* can be zero or more of the values *Py_DTSF_SIGN*,
- *Py_DTSF_ADD_DOT_0*, or *Py_DTSF_ALT*, or-ed together:
+ *flags* can be zero or more of the values ``Py_DTSF_SIGN``,
+ ``Py_DTSF_ADD_DOT_0``, or ``Py_DTSF_ALT``, or-ed together:
- * *Py_DTSF_SIGN* means to always precede the returned string with a sign
+ * ``Py_DTSF_SIGN`` means to always precede the returned string with a sign
character, even if *val* is non-negative.
- * *Py_DTSF_ADD_DOT_0* means to ensure that the returned string will not look
+ * ``Py_DTSF_ADD_DOT_0`` means to ensure that the returned string will not look
like an integer.
- * *Py_DTSF_ALT* means to apply "alternate" formatting rules. See the
+ * ``Py_DTSF_ALT`` means to apply "alternate" formatting rules. See the
documentation for the :c:func:`PyOS_snprintf` ``'#'`` specifier for
details.
- If *ptype* is non-NULL, then the value it points to will be set to one of
- *Py_DTST_FINITE*, *Py_DTST_INFINITE*, or *Py_DTST_NAN*, signifying that
+ If *ptype* is non-``NULL``, then the value it points to will be set to one of
+ ``Py_DTST_FINITE``, ``Py_DTST_INFINITE``, or ``Py_DTST_NAN``, signifying that
*val* is a finite number, an infinite number, or not a number, respectively.
The return value is a pointer to *buffer* with the converted string or
- *NULL* if the conversion failed. The caller is responsible for freeing the
+ ``NULL`` if the conversion failed. The caller is responsible for freeing the
returned string by calling :c:func:`PyMem_Free`.
.. versionadded:: 3.1
diff --git a/Doc/c-api/coro.rst b/Doc/c-api/coro.rst
index 2fe50b5d8c4473..af52d4f17374d0 100644
--- a/Doc/c-api/coro.rst
+++ b/Doc/c-api/coro.rst
@@ -23,7 +23,7 @@ return.
.. c:function:: int PyCoro_CheckExact(PyObject *ob)
- Return true if *ob*'s type is *PyCoro_Type*; *ob* must not be *NULL*.
+ Return true if *ob*'s type is :c:type:`PyCoro_Type`; *ob* must not be ``NULL``.
.. c:function:: PyObject* PyCoro_New(PyFrameObject *frame, PyObject *name, PyObject *qualname)
@@ -31,4 +31,4 @@ return.
Create and return a new coroutine object based on the *frame* object,
with ``__name__`` and ``__qualname__`` set to *name* and *qualname*.
A reference to *frame* is stolen by this function. The *frame* argument
- must not be *NULL*.
+ must not be ``NULL``.
diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst
index 78724619ea3c52..cb3267e3f82425 100644
--- a/Doc/c-api/datetime.rst
+++ b/Doc/c-api/datetime.rst
@@ -28,61 +28,61 @@ Type-check macros:
.. c:function:: int PyDate_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateType` or a subtype of
- :c:data:`PyDateTime_DateType`. *ob* must not be *NULL*.
+ :c:data:`PyDateTime_DateType`. *ob* must not be ``NULL``.
.. c:function:: int PyDate_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateType`. *ob* must not be
- *NULL*.
+ ``NULL``.
.. c:function:: int PyDateTime_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType` or a subtype of
- :c:data:`PyDateTime_DateTimeType`. *ob* must not be *NULL*.
+ :c:data:`PyDateTime_DateTimeType`. *ob* must not be ``NULL``.
.. c:function:: int PyDateTime_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType`. *ob* must not
- be *NULL*.
+ be ``NULL``.
.. c:function:: int PyTime_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TimeType` or a subtype of
- :c:data:`PyDateTime_TimeType`. *ob* must not be *NULL*.
+ :c:data:`PyDateTime_TimeType`. *ob* must not be ``NULL``.
.. c:function:: int PyTime_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TimeType`. *ob* must not be
- *NULL*.
+ ``NULL``.
.. c:function:: int PyDelta_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DeltaType` or a subtype of
- :c:data:`PyDateTime_DeltaType`. *ob* must not be *NULL*.
+ :c:data:`PyDateTime_DeltaType`. *ob* must not be ``NULL``.
.. c:function:: int PyDelta_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_DeltaType`. *ob* must not be
- *NULL*.
+ ``NULL``.
.. c:function:: int PyTZInfo_Check(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType` or a subtype of
- :c:data:`PyDateTime_TZInfoType`. *ob* must not be *NULL*.
+ :c:data:`PyDateTime_TZInfoType`. *ob* must not be ``NULL``.
.. c:function:: int PyTZInfo_CheckExact(PyObject *ob)
Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType`. *ob* must not be
- *NULL*.
+ ``NULL``.
Macros to create objects:
@@ -98,12 +98,28 @@ Macros to create objects:
minute, second and microsecond.
+.. c:function:: PyObject* PyDateTime_FromDateAndTimeAndFold(int year, int month, int day, int hour, int minute, int second, int usecond, int fold)
+
+ Return a :class:`datetime.datetime` object with the specified year, month, day, hour,
+ minute, second, microsecond and fold.
+
+ .. versionadded:: 3.6
+
+
.. c:function:: PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond)
Return a :class:`datetime.time` object with the specified hour, minute, second and
microsecond.
+.. c:function:: PyObject* PyTime_FromTimeAndFold(int hour, int minute, int second, int usecond, int fold)
+
+ Return a :class:`datetime.time` object with the specified hour, minute, second,
+ microsecond and fold.
+
+ .. versionadded:: 3.6
+
+
.. c:function:: PyObject* PyDelta_FromDSU(int days, int seconds, int useconds)
Return a :class:`datetime.timedelta` object representing the given number
@@ -128,7 +144,7 @@ Macros to create objects:
Macros to extract fields from date objects. The argument must be an instance of
:c:data:`PyDateTime_Date`, including subclasses (such as
-:c:data:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is
+:c:data:`PyDateTime_DateTime`). The argument must not be ``NULL``, and the type is
not checked:
.. c:function:: int PyDateTime_GET_YEAR(PyDateTime_Date *o)
@@ -148,7 +164,7 @@ not checked:
Macros to extract fields from datetime objects. The argument must be an
instance of :c:data:`PyDateTime_DateTime`, including subclasses. The argument
-must not be *NULL*, and the type is not checked:
+must not be ``NULL``, and the type is not checked:
.. c:function:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o)
@@ -170,8 +186,15 @@ must not be *NULL*, and the type is not checked:
Return the microsecond, as an int from 0 through 999999.
+.. c:function:: int PyDateTime_DATE_GET_FOLD(PyDateTime_DateTime *o)
+
+ Return the fold, as an int from 0 through 1.
+
+ .. versionadded:: 3.6
+
+
Macros to extract fields from time objects. The argument must be an instance of
-:c:data:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*,
+:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``,
and the type is not checked:
.. c:function:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o)
@@ -194,9 +217,16 @@ and the type is not checked:
Return the microsecond, as an int from 0 through 999999.
+.. c:function:: int PyDateTime_TIME_GET_FOLD(PyDateTime_Time *o)
+
+ Return the fold, as an int from 0 through 1.
+
+ .. versionadded:: 3.6
+
+
Macros to extract fields from time delta objects. The argument must be an
instance of :c:data:`PyDateTime_Delta`, including subclasses. The argument must
-not be *NULL*, and the type is not checked:
+not be ``NULL``, and the type is not checked:
.. c:function:: int PyDateTime_DELTA_GET_DAYS(PyDateTime_Delta *o)
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index b7225faf408ca0..ea7baf891e05e2 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -33,7 +33,7 @@ Dictionary Objects
.. c:function:: PyObject* PyDict_New()
- Return a new empty dictionary, or *NULL* on failure.
+ Return a new empty dictionary, or ``NULL`` on failure.
.. c:function:: PyObject* PyDictProxy_New(PyObject *mapping)
@@ -92,15 +92,19 @@ Dictionary Objects
.. c:function:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key)
- Return the object from dictionary *p* which has a key *key*. Return *NULL*
+ Return the object from dictionary *p* which has a key *key*. Return ``NULL``
if the key *key* is not present, but *without* setting an exception.
+ Note that exceptions which occur while calling :meth:`__hash__` and
+ :meth:`__eq__` methods will get suppressed.
+ To get error reporting use :c:func:`PyDict_GetItemWithError()` instead.
+
.. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key)
Variant of :c:func:`PyDict_GetItem` that does not suppress
- exceptions. Return *NULL* **with** an exception set if an exception
- occurred. Return *NULL* **without** an exception set if the key
+ exceptions. Return ``NULL`` **with** an exception set if an exception
+ occurred. Return ``NULL`` **without** an exception set if the key
wasn't present.
@@ -109,8 +113,13 @@ Dictionary Objects
This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a
:c:type:`const char\*`, rather than a :c:type:`PyObject\*`.
+ Note that exceptions which occur while calling :meth:`__hash__` and
+ :meth:`__eq__` methods and creating a temporary string object
+ will get suppressed.
+ To get error reporting use :c:func:`PyDict_GetItemWithError()` instead.
+
-.. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *default)
+.. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj)
This is the same as the Python-level :meth:`dict.setdefault`. If present, it
returns the value corresponding to *key* from the dictionary *p*. If the key
@@ -152,7 +161,7 @@ Dictionary Objects
function returns true for each pair in the dictionary, and false once all
pairs have been reported. The parameters *pkey* and *pvalue* should either
point to :c:type:`PyObject\*` variables that will be filled in with each key
- and value, respectively, or may be *NULL*. Any references returned through
+ and value, respectively, or may be ``NULL``. Any references returned through
them are borrowed. *ppos* should not be altered during iteration. Its
value represents offsets within the internal dictionary structure, and
since the structure is sparse, the offsets are not consecutive.
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 2bc1bd876a2fe2..19147fe53914ec 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -13,15 +13,15 @@ exception handling. It works somewhat like the POSIX :c:data:`errno` variable:
there is a global indicator (per thread) of the last error that occurred. Most
C API functions don't clear this on success, but will set it to indicate the
cause of the error on failure. Most C API functions also return an error
-indicator, usually *NULL* if they are supposed to return a pointer, or ``-1``
+indicator, usually ``NULL`` if they are supposed to return a pointer, or ``-1``
if they return an integer (exception: the :c:func:`PyArg_\*` functions
return ``1`` for success and ``0`` for failure).
Concretely, the error indicator consists of three object pointers: the
exception's type, the exception's value, and the traceback object. Any
-of those pointers can be NULL if non-set (although some combinations are
-forbidden, for example you can't have a non-NULL traceback if the exception
-type is NULL).
+of those pointers can be ``NULL`` if non-set (although some combinations are
+forbidden, for example you can't have a non-``NULL`` traceback if the exception
+type is ``NULL``).
When a function must fail because some function it called failed, it generally
doesn't set the error indicator; the function it called already set it. It is
@@ -53,8 +53,12 @@ Printing and clearing
.. c:function:: void PyErr_PrintEx(int set_sys_last_vars)
Print a standard traceback to ``sys.stderr`` and clear the error indicator.
- Call this function only when the error indicator is set. (Otherwise it will
- cause a fatal error!)
+ **Unless** the error is a ``SystemExit``. In that case the no traceback
+ is printed and Python process will exit with the error code specified by
+ the ``SystemExit`` instance.
+
+ Call this function **only** when the error indicator is set. Otherwise it
+ will cause a fatal error!
If *set_sys_last_vars* is nonzero, the variables :data:`sys.last_type`,
:data:`sys.last_value` and :data:`sys.last_traceback` will be set to the
@@ -77,13 +81,15 @@ Printing and clearing
in which the unraisable exception occurred. If possible,
the repr of *obj* will be printed in the warning message.
+ An exception must be set when calling this function.
+
Raising exceptions
==================
These functions help you set the current thread's error indicator.
For convenience, some of these functions will always return a
-NULL pointer for use in a ``return`` statement.
+``NULL`` pointer for use in a ``return`` statement.
.. c:function:: void PyErr_SetString(PyObject *type, const char *message)
@@ -102,7 +108,7 @@ NULL pointer for use in a ``return`` statement.
.. c:function:: PyObject* PyErr_Format(PyObject *exception, const char *format, ...)
- This function sets the error indicator and returns *NULL*. *exception*
+ This function sets the error indicator and returns ``NULL``. *exception*
should be a Python exception class. The *format* and subsequent
parameters help format the error message; they have the same meaning and
values as in :c:func:`PyUnicode_FromFormat`. *format* is an ASCII-encoded
@@ -131,7 +137,7 @@ NULL pointer for use in a ``return`` statement.
.. c:function:: PyObject* PyErr_NoMemory()
- This is a shorthand for ``PyErr_SetNone(PyExc_MemoryError)``; it returns *NULL*
+ This is a shorthand for ``PyErr_SetNone(PyExc_MemoryError)``; it returns ``NULL``
so an object allocation function can write ``return PyErr_NoMemory();`` when it
runs out of memory.
@@ -147,7 +153,7 @@ NULL pointer for use in a ``return`` statement.
and then calls ``PyErr_SetObject(type, object)``. On Unix, when the
:c:data:`errno` value is :const:`EINTR`, indicating an interrupted system call,
this calls :c:func:`PyErr_CheckSignals`, and if that set the error indicator,
- leaves it set to that. The function always returns *NULL*, so a wrapper
+ leaves it set to that. The function always returns ``NULL``, so a wrapper
function around a system call can write ``return PyErr_SetFromErrno(type);``
when the system call returns an error.
@@ -155,7 +161,7 @@ NULL pointer for use in a ``return`` statement.
.. c:function:: PyObject* PyErr_SetFromErrnoWithFilenameObject(PyObject *type, PyObject *filenameObject)
Similar to :c:func:`PyErr_SetFromErrno`, with the additional behavior that if
- *filenameObject* is not *NULL*, it is passed to the constructor of *type* as
+ *filenameObject* is not ``NULL``, it is passed to the constructor of *type* as
a third parameter. In the case of :exc:`OSError` exception,
this is used to define the :attr:`filename` attribute of the
exception instance.
@@ -186,34 +192,42 @@ NULL pointer for use in a ``return`` statement.
then it constructs a tuple object whose first item is the *ierr* value and whose
second item is the corresponding error message (gotten from
:c:func:`FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError,
- object)``. This function always returns *NULL*. Availability: Windows.
+ object)``. This function always returns ``NULL``.
+
+ .. availability:: Windows.
.. c:function:: PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)
Similar to :c:func:`PyErr_SetFromWindowsErr`, with an additional parameter
- specifying the exception type to be raised. Availability: Windows.
+ specifying the exception type to be raised.
+
+ .. availability:: Windows.
.. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the
filename is given as a C string. *filename* is decoded from the filesystem
- encoding (:func:`os.fsdecode`). Availability: Windows.
+ encoding (:func:`os.fsdecode`).
+
+ .. availability:: Windows.
.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)
Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, with an
additional parameter specifying the exception type to be raised.
- Availability: Windows.
+
+ .. availability:: Windows.
.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)
Similar to :c:func:`PyErr_SetExcFromWindowsErrWithFilenameObject`,
but accepts a second filename object.
- Availability: Windows.
+
+ .. availability:: Windows.
.. versionadded:: 3.4
@@ -221,7 +235,9 @@ NULL pointer for use in a ``return`` statement.
.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)
Similar to :c:func:`PyErr_SetFromWindowsErrWithFilename`, with an additional
- parameter specifying the exception type to be raised. Availability: Windows.
+ parameter specifying the exception type to be raised.
+
+ .. availability:: Windows.
.. c:function:: PyObject* PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
@@ -285,7 +301,7 @@ an error value).
.. c:function:: int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)
Issue a warning message. The *category* argument is a warning category (see
- below) or *NULL*; the *message* argument is a UTF-8 encoded string. *stack_level* is a
+ below) or ``NULL``; the *message* argument is a UTF-8 encoded string. *stack_level* is a
positive number giving a number of stack frames; the warning will be issued from
the currently executing line of code in that stack frame. A *stack_level* of 1
is the function calling :c:func:`PyErr_WarnEx`, 2 is the function above that,
@@ -301,7 +317,7 @@ an error value).
:mod:`warnings` module and the :option:`-W` option in the command line
documentation. There is no C API for warning control.
-.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *msg, PyObject *name, PyObject *path)
+.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
Much like :c:func:`PyErr_SetImportError` but this function allows for
specifying a subclass of :exc:`ImportError` to raise.
@@ -314,7 +330,7 @@ an error value).
Issue a warning message with explicit control over all warning attributes. This
is a straightforward wrapper around the Python function
:func:`warnings.warn_explicit`, see there for more information. The *module*
- and *registry* arguments may be set to *NULL* to get the default effect
+ and *registry* arguments may be set to ``NULL`` to get the default effect
described there.
.. versionadded:: 3.4
@@ -339,7 +355,7 @@ an error value).
.. c:function:: int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...)
Function similar to :c:func:`PyErr_WarnFormat`, but *category* is
- :exc:`ResourceWarning` and pass *source* to :func:`warnings.WarningMessage`.
+ :exc:`ResourceWarning` and it passes *source* to :func:`warnings.WarningMessage`.
.. versionadded:: 3.6
@@ -351,7 +367,7 @@ Querying the error indicator
Test whether the error indicator is set. If set, return the exception *type*
(the first argument to the last call to one of the :c:func:`PyErr_Set\*`
- functions or to :c:func:`PyErr_Restore`). If not set, return *NULL*. You do not
+ functions or to :c:func:`PyErr_Restore`). If not set, return ``NULL``. You do not
own a reference to the return value, so you do not need to :c:func:`Py_DECREF`
it.
@@ -381,9 +397,9 @@ Querying the error indicator
.. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)
Retrieve the error indicator into three variables whose addresses are passed.
- If the error indicator is not set, set all three variables to *NULL*. If it is
+ If the error indicator is not set, set all three variables to ``NULL``. If it is
set, it will be cleared and you own a reference to each object retrieved. The
- value and traceback object may be *NULL* even when the type object is not.
+ value and traceback object may be ``NULL`` even when the type object is not.
.. note::
@@ -403,8 +419,8 @@ Querying the error indicator
.. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
Set the error indicator from the three objects. If the error indicator is
- already set, it is cleared first. If the objects are *NULL*, the error
- indicator is cleared. Do not pass a *NULL* type and non-*NULL* value or
+ already set, it is cleared first. If the objects are ``NULL``, the error
+ indicator is cleared. Do not pass a ``NULL`` type and non-``NULL`` value or
traceback. The exception type should be a class. Do not pass an invalid
exception type or value. (Violating these rules will cause subtle problems
later.) This call takes away a reference to each object: you must own a
@@ -443,7 +459,7 @@ Querying the error indicator
Retrieve the exception info, as known from ``sys.exc_info()``. This refers
to an exception that was *already caught*, not to an exception that was
freshly raised. Returns new references for the three objects, any of which
- may be *NULL*. Does not modify the exception info state.
+ may be ``NULL``. Does not modify the exception info state.
.. note::
@@ -460,7 +476,7 @@ Querying the error indicator
Set the exception info, as known from ``sys.exc_info()``. This refers
to an exception that was *already caught*, not to an exception that was
freshly raised. This function steals the references of the arguments.
- To clear the exception state, pass *NULL* for all three arguments.
+ To clear the exception state, pass ``NULL`` for all three arguments.
For general rules about the three arguments, see :c:func:`PyErr_Restore`.
.. note::
@@ -500,13 +516,13 @@ Signal Handling
single: SIGINT
single: KeyboardInterrupt (built-in exception)
- This function simulates the effect of a :const:`SIGINT` signal arriving --- the
- next time :c:func:`PyErr_CheckSignals` is called, :exc:`KeyboardInterrupt` will
- be raised. It may be called without holding the interpreter lock.
-
- .. % XXX This was described as obsolete, but is used in
- .. % _thread.interrupt_main() (used from IDLE), so it's still needed.
+ Simulate the effect of a :const:`SIGINT` signal arriving. The next time
+ :c:func:`PyErr_CheckSignals` is called, the Python signal handler for
+ :const:`SIGINT` will be called.
+ If :const:`SIGINT` isn't handled by Python (it was set to
+ :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does
+ nothing.
.. c:function:: int PySignal_SetWakeupFd(int fd)
@@ -530,7 +546,7 @@ Exception Classes
This utility function creates and returns a new exception class. The *name*
argument must be the name of the new exception, a C string of the form
- ``module.classname``. The *base* and *dict* arguments are normally *NULL*.
+ ``module.classname``. The *base* and *dict* arguments are normally ``NULL``.
This creates a class object derived from :exc:`Exception` (accessible in C as
:c:data:`PyExc_Exception`).
@@ -544,7 +560,7 @@ Exception Classes
.. c:function:: PyObject* PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)
Same as :c:func:`PyErr_NewException`, except that the new exception class can
- easily be given a docstring: If *doc* is non-*NULL*, it will be used as the
+ easily be given a docstring: If *doc* is non-``NULL``, it will be used as the
docstring for the exception class.
.. versionadded:: 3.2
@@ -557,7 +573,7 @@ Exception Objects
Return the traceback associated with the exception as a new reference, as
accessible from Python through :attr:`__traceback__`. If there is no
- traceback associated, this returns *NULL*.
+ traceback associated, this returns ``NULL``.
.. c:function:: int PyException_SetTraceback(PyObject *ex, PyObject *tb)
@@ -571,12 +587,12 @@ Exception Objects
Return the context (another exception instance during whose handling *ex* was
raised) associated with the exception as a new reference, as accessible from
Python through :attr:`__context__`. If there is no context associated, this
- returns *NULL*.
+ returns ``NULL``.
.. c:function:: void PyException_SetContext(PyObject *ex, PyObject *ctx)
- Set the context associated with the exception to *ctx*. Use *NULL* to clear
+ Set the context associated with the exception to *ctx*. Use ``NULL`` to clear
it. There is no type check to make sure that *ctx* is an exception instance.
This steals a reference to *ctx*.
@@ -590,7 +606,7 @@ Exception Objects
.. c:function:: void PyException_SetCause(PyObject *ex, PyObject *cause)
- Set the cause associated with the exception to *cause*. Use *NULL* to clear
+ Set the cause associated with the exception to *cause*. Use ``NULL`` to clear
it. There is no type check to make sure that *cause* is either an exception
instance or :const:`None`. This steals a reference to *cause*.
@@ -637,7 +653,7 @@ The following functions are used to create and modify Unicode exceptions from C.
int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
Get the *start* attribute of the given exception object and place it into
- *\*start*. *start* must not be *NULL*. Return ``0`` on success, ``-1`` on
+ *\*start*. *start* must not be ``NULL``. Return ``0`` on success, ``-1`` on
failure.
.. c:function:: int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
@@ -652,7 +668,7 @@ The following functions are used to create and modify Unicode exceptions from C.
int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
Get the *end* attribute of the given exception object and place it into
- *\*end*. *end* must not be *NULL*. Return ``0`` on success, ``-1`` on
+ *\*end*. *end* must not be ``NULL``. Return ``0`` on success, ``-1`` on
failure.
.. c:function:: int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
@@ -952,9 +968,6 @@ Notes:
This is a base class for other standard exceptions.
(2)
- This is the same as :exc:`weakref.ReferenceError`.
-
-(3)
Only defined on Windows; protect code that uses this by testing that the
preprocessor macro ``MS_WINDOWS`` is defined.
diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst
index 6f2ecee51fd86a..63f1101caf5159 100644
--- a/Doc/c-api/file.rst
+++ b/Doc/c-api/file.rst
@@ -21,9 +21,9 @@ the :mod:`io` APIs instead.
Create a Python file object from the file descriptor of an already
opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline*
- can be *NULL* to use the defaults; *buffering* can be *-1* to use the
+ can be ``NULL`` to use the defaults; *buffering* can be *-1* to use the
default. *name* is ignored and kept for backward compatibility. Return
- *NULL* on failure. For a more comprehensive description of the arguments,
+ ``NULL`` on failure. For a more comprehensive description of the arguments,
please refer to the :func:`io.open` function documentation.
.. warning::
diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst
index 27a75e3e0c2eeb..fae321c250c41d 100644
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -34,12 +34,12 @@ Floating Point Objects
.. c:function:: PyObject* PyFloat_FromString(PyObject *str)
Create a :c:type:`PyFloatObject` object based on the string value in *str*, or
- *NULL* on failure.
+ ``NULL`` on failure.
.. c:function:: PyObject* PyFloat_FromDouble(double v)
- Create a :c:type:`PyFloatObject` object from *v*, or *NULL* on failure.
+ Create a :c:type:`PyFloatObject` object from *v*, or ``NULL`` on failure.
.. c:function:: double PyFloat_AsDouble(PyObject *pyfloat)
diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst
index 17279c732ae076..438381a7d2fe0f 100644
--- a/Doc/c-api/function.rst
+++ b/Doc/c-api/function.rst
@@ -26,7 +26,7 @@ There are a few functions specific to Python functions.
.. c:function:: int PyFunction_Check(PyObject *o)
Return true if *o* is a function object (has type :c:data:`PyFunction_Type`).
- The parameter must not be *NULL*.
+ The parameter must not be ``NULL``.
.. c:function:: PyObject* PyFunction_New(PyObject *code, PyObject *globals)
@@ -36,14 +36,14 @@ There are a few functions specific to Python functions.
The function's docstring and name are retrieved from the code object. *__module__*
is retrieved from *globals*. The argument defaults, annotations and closure are
- set to *NULL*. *__qualname__* is set to the same value as the function's name.
+ set to ``NULL``. *__qualname__* is set to the same value as the function's name.
.. c:function:: PyObject* PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
As :c:func:`PyFunction_New`, but also allows setting the function object's
- ``__qualname__`` attribute. *qualname* should be a unicode object or NULL;
- if NULL, the ``__qualname__`` attribute is set to the same value as its
+ ``__qualname__`` attribute. *qualname* should be a unicode object or ``NULL``;
+ if ``NULL``, the ``__qualname__`` attribute is set to the same value as its
``__name__`` attribute.
.. versionadded:: 3.3
@@ -69,27 +69,27 @@ There are a few functions specific to Python functions.
.. c:function:: PyObject* PyFunction_GetDefaults(PyObject *op)
Return the argument default values of the function object *op*. This can be a
- tuple of arguments or *NULL*.
+ tuple of arguments or ``NULL``.
.. c:function:: int PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
Set the argument default values for the function object *op*. *defaults* must be
- *Py_None* or a tuple.
+ ``Py_None`` or a tuple.
Raises :exc:`SystemError` and returns ``-1`` on failure.
.. c:function:: PyObject* PyFunction_GetClosure(PyObject *op)
- Return the closure associated with the function object *op*. This can be *NULL*
+ Return the closure associated with the function object *op*. This can be ``NULL``
or a tuple of cell objects.
.. c:function:: int PyFunction_SetClosure(PyObject *op, PyObject *closure)
Set the closure associated with the function object *op*. *closure* must be
- *Py_None* or a tuple of cell objects.
+ ``Py_None`` or a tuple of cell objects.
Raises :exc:`SystemError` and returns ``-1`` on failure.
@@ -97,12 +97,12 @@ There are a few functions specific to Python functions.
.. c:function:: PyObject *PyFunction_GetAnnotations(PyObject *op)
Return the annotations of the function object *op*. This can be a
- mutable dictionary or *NULL*.
+ mutable dictionary or ``NULL``.
.. c:function:: int PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
Set the annotations for the function object *op*. *annotations*
- must be a dictionary or *Py_None*.
+ must be a dictionary or ``Py_None``.
Raises :exc:`SystemError` and returns ``-1`` on failure.
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index f5e0d7ec9c79c3..95116d50bc4657 100644
--- a/Doc/c-api/gcsupport.rst
+++ b/Doc/c-api/gcsupport.rst
@@ -49,7 +49,7 @@ Constructors for container types must conform to two rules:
.. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)
Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the
- resized object or *NULL* on failure.
+ resized object or ``NULL`` on failure. *op* must not be tracked by the collector yet.
.. c:function:: void PyObject_GC_Track(PyObject *op)
@@ -66,6 +66,9 @@ Constructors for container types must conform to two rules:
A macro version of :c:func:`PyObject_GC_Track`. It should not be used for
extension modules.
+ .. deprecated:: 3.6
+ This macro is removed from Python 3.8.
+
Similarly, the deallocator for the object must conform to a similar pair of
rules:
@@ -95,6 +98,9 @@ rules:
A macro version of :c:func:`PyObject_GC_UnTrack`. It should not be used for
extension modules.
+ .. deprecated:: 3.6
+ This macro is removed from Python 3.8.
+
The :c:member:`~PyTypeObject.tp_traverse` handler accepts a function parameter of this type:
@@ -115,7 +121,7 @@ The :c:member:`~PyTypeObject.tp_traverse` handler must have the following type:
Traversal function for a container object. Implementations must call the
*visit* function for each object directly contained by *self*, with the
parameters to *visit* being the contained object and the *arg* value passed
- to the handler. The *visit* function must not be called with a *NULL*
+ to the handler. The *visit* function must not be called with a ``NULL``
object argument. If *visit* returns a non-zero value that value should be
returned immediately.
@@ -126,7 +132,7 @@ must name its arguments exactly *visit* and *arg*:
.. c:function:: void Py_VISIT(PyObject *o)
- If *o* is not *NULL*, call the *visit* callback, with arguments *o*
+ If *o* is not ``NULL``, call the *visit* callback, with arguments *o*
and *arg*. If *visit* returns a non-zero value, then return it.
Using this macro, :c:member:`~PyTypeObject.tp_traverse` handlers
look like::
@@ -139,7 +145,7 @@ must name its arguments exactly *visit* and *arg*:
return 0;
}
-The :c:member:`~PyTypeObject.tp_clear` handler must be of the :c:type:`inquiry` type, or *NULL*
+The :c:member:`~PyTypeObject.tp_clear` handler must be of the :c:type:`inquiry` type, or ``NULL``
if the object is immutable.
diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst
index 1efbae4fcba098..2226f58bc4292b 100644
--- a/Doc/c-api/gen.rst
+++ b/Doc/c-api/gen.rst
@@ -22,23 +22,23 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`.
.. c:function:: int PyGen_Check(PyObject *ob)
- Return true if *ob* is a generator object; *ob* must not be *NULL*.
+ Return true if *ob* is a generator object; *ob* must not be ``NULL``.
.. c:function:: int PyGen_CheckExact(PyObject *ob)
- Return true if *ob*'s type is *PyGen_Type*; *ob* must not be *NULL*.
+ Return true if *ob*'s type is :c:type:`PyGen_Type`; *ob* must not be ``NULL``.
.. c:function:: PyObject* PyGen_New(PyFrameObject *frame)
Create and return a new generator object based on the *frame* object.
A reference to *frame* is stolen by this function. The argument must not be
- *NULL*.
+ ``NULL``.
.. c:function:: PyObject* PyGen_NewWithQualName(PyFrameObject *frame, PyObject *name, PyObject *qualname)
Create and return a new generator object based on the *frame* object,
with ``__name__`` and ``__qualname__`` set to *name* and *qualname*.
A reference to *frame* is stolen by this function. The *frame* argument
- must not be *NULL*.
+ must not be ``NULL``.
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index 8cdc256e7c9e0e..764e2be4443013 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -14,7 +14,7 @@ Importing Modules
single: modules (in module sys)
This is a simplified interface to :c:func:`PyImport_ImportModuleEx` below,
- leaving the *globals* and *locals* arguments set to *NULL* and *level* set
+ leaving the *globals* and *locals* arguments set to ``NULL`` and *level* set
to 0. When the *name*
argument contains a dot (when it specifies a submodule of a package), the
*fromlist* argument is set to the list ``['*']`` so that the return value is the
@@ -22,7 +22,7 @@ Importing Modules
be the case. (Unfortunately, this has an additional side effect when *name* in
fact specifies a subpackage instead of a submodule: the submodules specified in
the package's ``__all__`` variable are loaded.) Return a new reference to the
- imported module, or *NULL* with an exception set on failure. A failing
+ imported module, or ``NULL`` with an exception set on failure. A failing
import of a module doesn't leave the module in :data:`sys.modules`.
This function always uses absolute imports.
@@ -47,7 +47,7 @@ Importing Modules
function :func:`__import__`.
The return value is a new reference to the imported module or top-level
- package, or *NULL* with an exception set on failure. Like for
+ package, or ``NULL`` with an exception set on failure. Like for
:func:`__import__`, the return value when a submodule of a package was
requested is normally the top-level package, unless a non-empty *fromlist*
was given.
@@ -63,7 +63,7 @@ Importing Modules
this function directly.
The return value is a new reference to the imported module or top-level package,
- or *NULL* with an exception set on failure. Like for :func:`__import__`,
+ or ``NULL`` with an exception set on failure. Like for :func:`__import__`,
the return value when a submodule of a package was requested is normally the
top-level package, unless a non-empty *fromlist* was given.
@@ -91,7 +91,7 @@ Importing Modules
.. c:function:: PyObject* PyImport_ReloadModule(PyObject *m)
- Reload a module. Return a new reference to the reloaded module, or *NULL* with
+ Reload a module. Return a new reference to the reloaded module, or ``NULL`` with
an exception set on failure (the module still exists in this case).
@@ -100,7 +100,7 @@ Importing Modules
Return the module object corresponding to a module name. The *name* argument
may be of the form ``package.module``. First check the modules dictionary if
there's one there, and if not, create a new one and insert it in the modules
- dictionary. Return *NULL* with an exception set on failure.
+ dictionary. Return ``NULL`` with an exception set on failure.
.. note::
@@ -125,7 +125,7 @@ Importing Modules
Given a module name (possibly of the form ``package.module``) and a code object
read from a Python bytecode file or obtained from the built-in function
:func:`compile`, load the module. Return a new reference to the module object,
- or *NULL* with an exception set if an error occurred. *name*
+ or ``NULL`` with an exception set if an error occurred. *name*
is removed from :attr:`sys.modules` in error cases, even if *name* was already
in :attr:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`. Leaving
incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of
@@ -207,8 +207,8 @@ Importing Modules
.. c:function:: PyObject* PyImport_GetModule(PyObject *name)
Return the already imported module with the given name. If the
- module has not been imported yet then returns NULL but does not set
- an error. Returns NULL and sets an error if the lookup failed.
+ module has not been imported yet then returns ``NULL`` but does not set
+ an error. Returns ``NULL`` and sets an error if the lookup failed.
.. versionadded:: 3.7
@@ -277,7 +277,7 @@ Importing Modules
.. c:var:: const struct _frozen* PyImport_FrozenModules
This pointer is initialized to point to an array of :c:type:`struct _frozen`
- records, terminated by one whose members are all *NULL* or zero. When a frozen
+ records, terminated by one whose members are all ``NULL`` or zero. When a frozen
module is imported, it is searched in this table. Third-party code could play
tricks with this to provide a dynamically created collection of frozen modules.
@@ -310,7 +310,7 @@ Importing Modules
.. c:function:: int PyImport_ExtendInittab(struct _inittab *newtab)
Add a collection of modules to the table of built-in modules. The *newtab*
- array must end with a sentinel entry which contains *NULL* for the :attr:`name`
+ array must end with a sentinel entry which contains ``NULL`` for the :attr:`name`
field; failure to provide the sentinel value can result in a memory fault.
Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to
extend the internal table. In the event of failure, no modules are added to the
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index bae49d5ba8125e..2822b88cc3359f 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -31,9 +31,13 @@ The following functions can be safely called before Python is initialized:
* :c:func:`Py_SetProgramName`
* :c:func:`Py_SetPythonHome`
* :c:func:`Py_SetStandardStreamEncoding`
+ * :c:func:`PySys_AddWarnOption`
+ * :c:func:`PySys_AddXOption`
+ * :c:func:`PySys_ResetWarnOptions`
* Informative functions:
+ * :c:func:`Py_IsInitialized`
* :c:func:`PyMem_GetAllocator`
* :c:func:`PyObject_GetArenaAllocator`
* :c:func:`Py_GetBuildInfo`
@@ -153,7 +157,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
See :pep:`529` for more details.
- Availability: Windows.
+ .. availability:: Windows.
.. c:var:: Py_LegacyWindowsStdioFlag
@@ -165,7 +169,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
See :pep:`528` for more details.
- Availability: Windows.
+ .. availability:: Windows.
.. c:var:: Py_NoSiteFlag
@@ -273,8 +277,8 @@ Initializing and finalizing the interpreter
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.
+ 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.
@@ -322,7 +326,7 @@ Process-wide parameters
It overrides :envvar:`PYTHONIOENCODING` values, and allows embedding code
to control IO encoding when the environment variable does not work.
- ``encoding`` and/or ``errors`` may be NULL to use
+ *encoding* and/or *errors* may be ``NULL`` to use
:envvar:`PYTHONIOENCODING` and/or default values (depending on other
settings).
@@ -840,8 +844,8 @@ code, or when embedding the Python interpreter:
.. c:function:: PyThreadState* PyEval_SaveThread()
Release the global interpreter lock (if it has been created and thread
- support is enabled) and reset the thread state to *NULL*, returning the
- previous thread state (which is not *NULL*). If the lock has been created,
+ support is enabled) and reset the thread state to ``NULL``, returning the
+ previous thread state (which is not ``NULL``). If the lock has been created,
the current thread must have acquired it.
@@ -849,21 +853,27 @@ code, or when embedding the Python interpreter:
Acquire the global interpreter lock (if it has been created and thread
support is enabled) and set the thread state to *tstate*, which must not be
- *NULL*. If the lock has been created, the current thread must not have
+ ``NULL``. If the lock has been created, the current thread must not have
acquired it, otherwise deadlock ensues.
+ .. note::
+ Calling this function from a thread when the runtime is finalizing
+ will terminate the thread, even if the thread was not created by Python.
+ You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to
+ check if the interpreter is in process of being finalized before calling
+ this function to avoid unwanted termination.
.. c:function:: PyThreadState* PyThreadState_Get()
Return the current thread state. The global interpreter lock must be held.
- When the current thread state is *NULL*, this issues a fatal error (so that
- the caller needn't check for *NULL*).
+ When the current thread state is ``NULL``, this issues a fatal error (so that
+ the caller needn't check for ``NULL``).
.. c:function:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate)
Swap the current thread state with the thread state given by the argument
- *tstate*, which may be *NULL*. The global interpreter lock must be held
+ *tstate*, which may be ``NULL``. The global interpreter lock must be held
and is not released.
@@ -899,6 +909,12 @@ with sub-interpreters:
When the function returns, the current thread will hold the GIL and be able
to call arbitrary Python code. Failure is a fatal error.
+ .. note::
+ Calling this function from a thread when the runtime is finalizing
+ will terminate the thread, even if the thread was not created by Python.
+ You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to
+ check if the interpreter is in process of being finalized before calling
+ this function to avoid unwanted termination.
.. c:function:: void PyGILState_Release(PyGILState_STATE)
@@ -1018,7 +1034,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. c:function:: PY_INT64_T PyInterpreterState_GetID(PyInterpreterState *interp)
Return the interpreter's unique ID. If there was any error in doing
- so then -1 is returned and an error is set.
+ so then ``-1`` is returned and an error is set.
.. versionadded:: 3.7
@@ -1028,7 +1044,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
Return a dictionary in which extensions can store thread-specific state
information. Each extension should use a unique key to use to store state in
the dictionary. It is okay to call this function when no current thread state
- is available. If this function returns *NULL*, no exception has been raised and
+ is available. If this function returns ``NULL``, no exception has been raised and
the caller should assume no current thread state is available.
@@ -1049,7 +1065,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate)
Acquire the global interpreter lock and set the current thread state to
- *tstate*, which should not be *NULL*. The lock must have been created earlier.
+ *tstate*, which should not be ``NULL``. The lock must have been created earlier.
If this thread already has the lock, deadlock ensues.
:c:func:`PyEval_RestoreThread` is a higher-level function which is always
@@ -1058,9 +1074,9 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. c:function:: void PyEval_ReleaseThread(PyThreadState *tstate)
- Reset the current thread state to *NULL* and release the global interpreter
+ Reset the current thread state to ``NULL`` and release the global interpreter
lock. The lock must have been created earlier and must be held by the current
- thread. The *tstate* argument, which must not be *NULL*, is only used to check
+ thread. The *tstate* argument, which must not be ``NULL``, is only used to check
that it represents the current thread state --- if it isn't, a fatal error is
reported.
@@ -1125,7 +1141,7 @@ using the following functions:
The return value points to the first thread state created in the new
sub-interpreter. This thread state is made in the current thread state.
Note that no actual thread is created; see the discussion of thread states
- below. If creation of the new interpreter is unsuccessful, *NULL* is
+ below. If creation of the new interpreter is unsuccessful, ``NULL`` is
returned; no exception is set since the exception state is stored in the
current thread state and there may not be a current thread state. (Like all
other Python/C API functions, the global interpreter lock must be held before
@@ -1156,7 +1172,7 @@ using the following functions:
Destroy the (sub-)interpreter represented by the given thread state. The given
thread state must be the current thread state. See the discussion of thread
- states below. When the call returns, the current thread state is *NULL*. All
+ states below. When the call returns, the current thread state is ``NULL``. All
thread states associated with this interpreter are destroyed. (The global
interpreter lock must be held before calling this function and is still held
when it returns.) :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that
@@ -1263,27 +1279,27 @@ Python-level trace functions in previous versions.
:const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION`, :const:`PyTrace_C_RETURN`,
or :const:`PyTrace_OPCODE`, and *arg* depends on the value of *what*:
- +------------------------------+--------------------------------------+
- | Value of *what* | Meaning of *arg* |
- +==============================+======================================+
- | :const:`PyTrace_CALL` | Always :c:data:`Py_None`. |
- +------------------------------+--------------------------------------+
- | :const:`PyTrace_EXCEPTION` | Exception information as returned by |
- | | :func:`sys.exc_info`. |
- +------------------------------+--------------------------------------+
- | :const:`PyTrace_LINE` | Always :c:data:`Py_None`. |
- +------------------------------+--------------------------------------+
- | :const:`PyTrace_RETURN` | Value being returned to the caller, |
- | | or *NULL* if caused by an exception. |
- +------------------------------+--------------------------------------+
- | :const:`PyTrace_C_CALL` | Function object being called. |
- +------------------------------+--------------------------------------+
- | :const:`PyTrace_C_EXCEPTION` | Function object being called. |
- +------------------------------+--------------------------------------+
- | :const:`PyTrace_C_RETURN` | Function object being called. |
- +------------------------------+--------------------------------------+
- | :const:`PyTrace_OPCODE` | Always :c:data:`Py_None`. |
- +------------------------------+--------------------------------------+
+ +------------------------------+----------------------------------------+
+ | Value of *what* | Meaning of *arg* |
+ +==============================+========================================+
+ | :const:`PyTrace_CALL` | Always :c:data:`Py_None`. |
+ +------------------------------+----------------------------------------+
+ | :const:`PyTrace_EXCEPTION` | Exception information as returned by |
+ | | :func:`sys.exc_info`. |
+ +------------------------------+----------------------------------------+
+ | :const:`PyTrace_LINE` | Always :c:data:`Py_None`. |
+ +------------------------------+----------------------------------------+
+ | :const:`PyTrace_RETURN` | Value being returned to the caller, |
+ | | or ``NULL`` if caused by an exception. |
+ +------------------------------+----------------------------------------+
+ | :const:`PyTrace_C_CALL` | Function object being called. |
+ +------------------------------+----------------------------------------+
+ | :const:`PyTrace_C_EXCEPTION` | Function object being called. |
+ +------------------------------+----------------------------------------+
+ | :const:`PyTrace_C_RETURN` | Function object being called. |
+ +------------------------------+----------------------------------------+
+ | :const:`PyTrace_OPCODE` | Always :c:data:`Py_None`. |
+ +------------------------------+----------------------------------------+
.. c:var:: int PyTrace_CALL
@@ -1347,7 +1363,7 @@ Python-level trace functions in previous versions.
.. c:function:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)
Set the profiler function to *func*. The *obj* parameter is passed to the
- function as its first parameter, and may be any Python object, or *NULL*. If
+ function as its first parameter, and may be any Python object, or ``NULL``. If
the profile function needs to maintain state, using a different value for *obj*
for each thread provides a convenient and thread-safe place to store it. The
profile function is called for all monitored events except :const:`PyTrace_LINE`
@@ -1379,6 +1395,11 @@ These functions are only intended to be used by advanced debugging tools.
Return the interpreter state object at the head of the list of all such objects.
+.. c:function:: PyInterpreterState* PyInterpreterState_Main()
+
+ Return the main interpreter state object.
+
+
.. c:function:: PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp)
Return the next interpreter state object after *interp* from the list of all
@@ -1465,7 +1486,7 @@ is not possible due to its implementation being opaque at build time.
.. c:function:: Py_tss_t* PyThread_tss_alloc()
Return a value which is the same state as a value initialized with
- :c:macro:`Py_tss_NEEDS_INIT`, or *NULL* in the case of dynamic allocation
+ :c:macro:`Py_tss_NEEDS_INIT`, or ``NULL`` in the case of dynamic allocation
failure.
@@ -1484,7 +1505,7 @@ is not possible due to its implementation being opaque at build time.
Methods
~~~~~~~
-The parameter *key* of these functions must not be *NULL*. Moreover, the
+The parameter *key* of these functions must not be ``NULL``. Moreover, the
behaviors of :c:func:`PyThread_tss_set` and :c:func:`PyThread_tss_get` are
undefined if the given :c:type:`Py_tss_t` has not been initialized by
:c:func:`PyThread_tss_create`.
@@ -1524,7 +1545,7 @@ undefined if the given :c:type:`Py_tss_t` has not been initialized by
.. c:function:: void* PyThread_tss_get(Py_tss_t *key)
Return the :c:type:`void\*` value associated with a TSS key in the current
- thread. This returns *NULL* if no value is associated with the key in the
+ thread. This returns ``NULL`` if no value is associated with the key in the
current thread.
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index 15006100c7366a..7c76ed878da962 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -48,7 +48,8 @@ Include Files
All function, type and macro definitions needed to use the Python/C API are
included in your code by the following line::
- #include "Python.h"
+ #define PY_SSIZE_T_CLEAN
+ #include
This implies inclusion of the following standard headers: ````,
````, ````, ````, ```` and ````
@@ -60,15 +61,20 @@ This implies inclusion of the following standard headers: ````,
headers on some systems, you *must* include :file:`Python.h` before any standard
headers are included.
+ It is recommended to always define ``PY_SSIZE_T_CLEAN`` before including
+ ``Python.h``. See :ref:`arg-parsing` for a description of this macro.
+
All user visible names defined by Python.h (except those defined by the included
standard headers) have one of the prefixes ``Py`` or ``_Py``. Names beginning
with ``_Py`` are for internal use by the Python implementation and should not be
used by extension writers. Structure member names do not have a reserved prefix.
-**Important:** user code should never define names that begin with ``Py`` or
-``_Py``. This confuses the reader, and jeopardizes the portability of the user
-code to future Python versions, which may define additional names beginning with
-one of these prefixes.
+.. note::
+
+ User code should never define names that begin with ``Py`` or ``_Py``. This
+ confuses the reader, and jeopardizes the portability of the user code to
+ future Python versions, which may define additional names beginning with one
+ of these prefixes.
The header files are typically installed with Python. On Unix, these are
located in the directories :file:`{prefix}/include/pythonversion/` and
@@ -86,9 +92,9 @@ multi-platform builds since the platform independent headers under
:envvar:`prefix` include the platform specific headers from
:envvar:`exec_prefix`.
-C++ users should note that though the API is defined entirely using C, the
-header files do properly declare the entry points to be ``extern "C"``, so there
-is no need to do anything special to use the API from C++.
+C++ users should note that although the API is defined entirely using C, the
+header files properly declare the entry points to be ``extern "C"``. As a result,
+there is no need to do anything special to use the API from C++.
Useful macros
@@ -146,7 +152,7 @@ complete listing.
.. c:macro:: Py_GETENV(s)
- Like ``getenv(s)``, but returns *NULL* if :option:`-E` was passed on the
+ Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set).
.. c:macro:: Py_UNUSED(arg)
@@ -156,6 +162,39 @@ complete listing.
.. versionadded:: 3.4
+.. c:macro:: PyDoc_STRVAR(name, str)
+
+ Creates a variable with name ``name`` that can be used in docstrings.
+ If Python is built without docstrings, the value will be empty.
+
+ Use :c:macro:`PyDoc_STRVAR` for docstrings to support building
+ Python without docstrings, as specified in :pep:`7`.
+
+ Example::
+
+ PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
+
+ static PyMethodDef deque_methods[] = {
+ // ...
+ {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc},
+ // ...
+ }
+
+.. c:macro:: PyDoc_STR(str)
+
+ Creates a docstring for the given input string or an empty string
+ if docstrings are disabled.
+
+ Use :c:macro:`PyDoc_STR` in specifying docstrings to support
+ building Python without docstrings, as specified in :pep:`7`.
+
+ Example::
+
+ static PyMethodDef pysqlite_row_methods[] = {
+ {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
+ PyDoc_STR("Returns the keys of the row.")},
+ {NULL, NULL}
+ };
.. _api-objects:
@@ -457,7 +496,7 @@ functions in the Python/C API can raise exceptions, unless an explicit claim is
made otherwise in a function's documentation. In general, when a function
encounters an error, it sets an exception, discards any object references that
it owns, and returns an error indicator. If not documented otherwise, this
-indicator is either *NULL* or ``-1``, depending on the function's return type.
+indicator is either ``NULL`` or ``-1``, depending on the function's return type.
A few functions return a Boolean true/false result, with false indicating an
error. Very few functions return no explicit error indicator or have an
ambiguous return value, and require explicit testing for errors with
@@ -472,13 +511,13 @@ using global storage in an unthreaded application). A thread can be in one of
two states: an exception has occurred, or not. The function
:c:func:`PyErr_Occurred` can be used to check for this: it returns a borrowed
reference to the exception type object when an exception has occurred, and
-*NULL* otherwise. There are a number of functions to set the exception state:
+``NULL`` otherwise. There are a number of functions to set the exception state:
:c:func:`PyErr_SetString` is the most common (though not the most general)
function to set the exception state, and :c:func:`PyErr_Clear` clears the
exception state.
The full exception state consists of three objects (all of which can be
-*NULL*): the exception type, the corresponding exception value, and the
+``NULL``): the exception type, the corresponding exception value, and the
traceback. These have the same meanings as the Python result of
``sys.exc_info()``; however, they are not the same: the Python objects represent
the last exception being handled by a Python :keyword:`try` ...
@@ -579,10 +618,10 @@ Here is the corresponding C code, in all its glory::
This example represents an endorsed use of the ``goto`` statement in C!
It illustrates the use of :c:func:`PyErr_ExceptionMatches` and
:c:func:`PyErr_Clear` to handle specific exceptions, and the use of
-:c:func:`Py_XDECREF` to dispose of owned references that may be *NULL* (note the
+:c:func:`Py_XDECREF` to dispose of owned references that may be ``NULL`` (note the
``'X'`` in the name; :c:func:`Py_DECREF` would crash when confronted with a
-*NULL* reference). It is important that the variables used to hold owned
-references are initialized to *NULL* for this to work; likewise, the proposed
+``NULL`` reference). It is important that the variables used to hold owned
+references are initialized to ``NULL`` for this to work; likewise, the proposed
return value is initialized to ``-1`` (failure) and only set to success after
the final call made is successful.
diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst
index 2ba444d1de6d24..6507da9c7f0a51 100644
--- a/Doc/c-api/iter.rst
+++ b/Doc/c-api/iter.rst
@@ -16,8 +16,8 @@ There are two functions specifically for working with iterators.
Return the next value from the iteration *o*. The object must be an iterator
(it is up to the caller to check this). If there are no remaining values,
- returns *NULL* with no exception set. If an error occurs while retrieving
- the item, returns *NULL* and passes along the exception.
+ returns ``NULL`` with no exception set. If an error occurs while retrieving
+ the item, returns ``NULL`` and passes along the exception.
To write a loop which iterates over an iterator, the C code should look
something like this::
@@ -29,7 +29,7 @@ something like this::
/* propagate error */
}
- while (item = PyIter_Next(iterator)) {
+ while ((item = PyIter_Next(iterator))) {
/* do something with item */
...
/* release reference when done */
diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst
index 5b263a7b1cdf04..0dde88470e3a39 100644
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -33,7 +33,7 @@ List Objects
.. c:function:: PyObject* PyList_New(Py_ssize_t len)
- Return a new list of length *len* on success, or *NULL* on failure.
+ Return a new list of length *len* on success, or ``NULL`` on failure.
.. note::
@@ -59,9 +59,9 @@ List Objects
.. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)
Return the object at position *index* in the list pointed to by *list*. The
- position must be positive, indexing from the end of the list is not
- supported. If *index* is out of bounds, return *NULL* and set an
- :exc:`IndexError` exception.
+ position must be non-negative; indexing from the end of the list is not
+ supported. If *index* is out of bounds (<0 or >=len(list)),
+ return ``NULL`` and set an :exc:`IndexError` exception.
.. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)
@@ -71,8 +71,9 @@ List Objects
.. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
- Set the item at index *index* in list to *item*. Return ``0`` on success
- or ``-1`` on failure.
+ Set the item at index *index* in list to *item*. Return ``0`` on success.
+ If *index* is out of bounds, return ``-1`` and set an :exc:`IndexError`
+ exception.
.. note::
@@ -110,18 +111,17 @@ List Objects
.. c:function:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high)
Return a list of the objects in *list* containing the objects *between* *low*
- and *high*. Return *NULL* and set an exception if unsuccessful. Analogous
- to ``list[low:high]``. Negative indices, as when slicing from Python, are not
- supported.
+ and *high*. Return ``NULL`` and set an exception if unsuccessful. Analogous
+ to ``list[low:high]``. Indexing from the end of the list is not supported.
.. c:function:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist)
Set the slice of *list* between *low* and *high* to the contents of
*itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may
- be *NULL*, indicating the assignment of an empty list (slice deletion).
- Return ``0`` on success, ``-1`` on failure. Negative indices, as when
- slicing from Python, are not supported.
+ be ``NULL``, indicating the assignment of an empty list (slice deletion).
+ Return ``0`` on success, ``-1`` on failure. Indexing from the end of the
+ list is not supported.
.. c:function:: int PyList_Sort(PyObject *list)
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 4f16b578eb5999..08cf6a9bf25a4f 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -38,7 +38,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: PyObject* PyLong_FromLong(long v)
- Return a new :c:type:`PyLongObject` object from *v*, or *NULL* on failure.
+ Return a new :c:type:`PyLongObject` object from *v*, or ``NULL`` on failure.
The current implementation keeps an array of integer objects for all integers
between ``-5`` and ``256``, when you create an int in that range you actually
@@ -50,43 +50,43 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: PyObject* PyLong_FromUnsignedLong(unsigned long v)
Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long`, or
- *NULL* on failure.
+ ``NULL`` on failure.
.. c:function:: PyObject* PyLong_FromSsize_t(Py_ssize_t v)
Return a new :c:type:`PyLongObject` object from a C :c:type:`Py_ssize_t`, or
- *NULL* on failure.
+ ``NULL`` on failure.
.. c:function:: PyObject* PyLong_FromSize_t(size_t v)
Return a new :c:type:`PyLongObject` object from a C :c:type:`size_t`, or
- *NULL* on failure.
+ ``NULL`` on failure.
.. c:function:: PyObject* PyLong_FromLongLong(long long v)
- Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or *NULL*
+ Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or ``NULL``
on failure.
.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v)
Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long long`,
- or *NULL* on failure.
+ or ``NULL`` on failure.
.. c:function:: PyObject* PyLong_FromDouble(double v)
Return a new :c:type:`PyLongObject` object from the integer part of *v*, or
- *NULL* on failure.
+ ``NULL`` on failure.
.. c:function:: PyObject* PyLong_FromString(const char *str, char **pend, int base)
Return a new :c:type:`PyLongObject` based on the string value in *str*, which
- is interpreted according to the radix in *base*. If *pend* is non-*NULL*,
+ is interpreted according to the radix in *base*. If *pend* is non-``NULL``,
*\*pend* will point to the first character in *str* which follows the
representation of the number. If *base* is ``0``, *str* is interpreted using
the :ref:`integers` definition; in this case, leading zeros in a
@@ -137,7 +137,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
:c:type:`long`.
- Returns -1 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow)
@@ -151,7 +151,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
return ``-1``; otherwise, set *\*overflow* to ``0``. If any other exception
occurs set *\*overflow* to ``0`` and return ``-1`` as usual.
- Returns -1 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: long long PyLong_AsLongLong(PyObject *obj)
@@ -164,9 +164,9 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
(if present) to convert it to a :c:type:`PyLongObject`.
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
- :c:type:`long`.
+ :c:type:`long long`.
- Returns -1 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: long long PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow)
@@ -180,7 +180,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
and return ``-1``; otherwise, set *\*overflow* to ``0``. If any other
exception occurs set *\*overflow* to ``0`` and return ``-1`` as usual.
- Returns -1 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionadded:: 3.2
@@ -197,7 +197,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
:c:type:`Py_ssize_t`.
- Returns -1 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong)
@@ -259,7 +259,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
If the value of *obj* is out of range for an :c:type:`unsigned long`,
return the reduction of that value modulo ``ULONG_MAX + 1``.
- Returns -1 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``(unsigned long)-1`` on error. Use :c:func:`PyErr_Occurred` to
+ disambiguate.
.. c:function:: unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj)
@@ -271,7 +272,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
If the value of *obj* is out of range for an :c:type:`unsigned long long`,
return the reduction of that value modulo ``PY_ULLONG_MAX + 1``.
- Returns -1 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``(unsigned long long)-1`` on error. Use :c:func:`PyErr_Occurred`
+ to disambiguate.
.. c:function:: double PyLong_AsDouble(PyObject *pylong)
@@ -282,7 +284,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
:c:type:`double`.
- Returns -1.0 on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``-1.0`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: void* PyLong_AsVoidPtr(PyObject *pylong)
@@ -292,4 +294,4 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
is only assured to produce a usable :c:type:`void` pointer for values created
with :c:func:`PyLong_FromVoidPtr`.
- Returns NULL on error. Use :c:func:`PyErr_Occurred` to disambiguate.
+ Returns ``NULL`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst
index 308a9761f87ea9..abdc2aea758ba1 100644
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -5,11 +5,16 @@
Mapping Protocol
================
+See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
+:c:func:`PyObject_DelItem`.
+
.. c:function:: int PyMapping_Check(PyObject *o)
- Return ``1`` if the object provides mapping protocol, and ``0`` otherwise. This
- function always succeeds.
+ Return ``1`` if the object provides mapping protocol or supports slicing,
+ and ``0`` otherwise. Note that it returns ``1`` for Python classes with
+ a :meth:`__getitem__` method since in general case it is impossible to
+ determine what type of keys it supports. This function always succeeds.
.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
@@ -17,41 +22,63 @@ Mapping Protocol
.. index:: builtin: len
- Returns the number of keys in object *o* on success, and ``-1`` on failure. For
- objects that do not provide mapping protocol, this is equivalent to the Python
- expression ``len(o)``.
+ Returns the number of keys in object *o* on success, and ``-1`` on failure.
+ This is equivalent to the Python expression ``len(o)``.
-.. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key)
+.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key)
+
+ Return element of *o* corresponding to the string *key* or ``NULL`` on failure.
+ This is the equivalent of the Python expression ``o[key]``.
+ See also :c:func:`PyObject_GetItem`.
+
+
+.. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v)
- Remove the mapping for object *key* from the object *o*. Return ``-1`` on
- failure. This is equivalent to the Python statement ``del o[key]``.
+ Map the string *key* to the value *v* in object *o*. Returns ``-1`` on
+ failure. This is the equivalent of the Python statement ``o[key] = v``.
+ See also :c:func:`PyObject_SetItem`.
.. c:function:: int PyMapping_DelItem(PyObject *o, PyObject *key)
- Remove the mapping for object *key* from the object *o*. Return ``-1`` on
- failure. This is equivalent to the Python statement ``del o[key]``.
+ Remove the mapping for the object *key* from the object *o*. Return ``-1``
+ on failure. This is equivalent to the Python statement ``del o[key]``.
+ This is an alias of :c:func:`PyObject_DelItem`.
-.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key)
+.. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key)
- On success, return ``1`` if the mapping object has the key *key* and ``0``
- otherwise. This is equivalent to the Python expression ``key in o``.
- This function always succeeds.
+ Remove the mapping for the string *key* from the object *o*. Return ``-1``
+ on failure. This is equivalent to the Python statement ``del o[key]``.
.. c:function:: int PyMapping_HasKey(PyObject *o, PyObject *key)
- Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This
- is equivalent to the Python expression ``key in o``. This function always
- succeeds.
+ Return ``1`` if the mapping object has the key *key* and ``0`` otherwise.
+ This is equivalent to the Python expression ``key in o``.
+ This function always succeeds.
+
+ Note that exceptions which occur while calling the :meth:`__getitem__`
+ method will get suppressed.
+ To get error reporting use :c:func:`PyObject_GetItem()` instead.
+
+
+.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key)
+
+ Return ``1`` if the mapping object has the key *key* and ``0`` otherwise.
+ This is equivalent to the Python expression ``key in o``.
+ This function always succeeds.
+
+ Note that exceptions which occur while calling the :meth:`__getitem__`
+ method and creating a temporary string object will get suppressed.
+ To get error reporting use :c:func:`PyMapping_GetItemString()` instead.
.. c:function:: PyObject* PyMapping_Keys(PyObject *o)
On success, return a list of the keys in object *o*. On failure, return
- *NULL*.
+ ``NULL``.
.. versionchanged:: 3.7
Previously, the function returned a list or a tuple.
@@ -60,7 +87,7 @@ Mapping Protocol
.. c:function:: PyObject* PyMapping_Values(PyObject *o)
On success, return a list of the values in object *o*. On failure, return
- *NULL*.
+ ``NULL``.
.. versionchanged:: 3.7
Previously, the function returned a list or a tuple.
@@ -69,19 +96,7 @@ Mapping Protocol
.. c:function:: PyObject* PyMapping_Items(PyObject *o)
On success, return a list of the items in object *o*, where each item is a
- tuple containing a key-value pair. On failure, return *NULL*.
+ tuple containing a key-value pair. On failure, return ``NULL``.
.. versionchanged:: 3.7
Previously, the function returned a list or a tuple.
-
-
-.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key)
-
- Return element of *o* corresponding to the object *key* or *NULL* on failure.
- This is the equivalent of the Python expression ``o[key]``.
-
-
-.. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v)
-
- Map the object *key* to the value *v* in object *o*. Returns ``-1`` on failure.
- This is the equivalent of the Python statement ``o[key] = v``.
diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst
index c6d1d02a2fa510..8c444223b9d282 100644
--- a/Doc/c-api/marshal.rst
+++ b/Doc/c-api/marshal.rst
@@ -16,7 +16,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.
-*Py_MARSHAL_VERSION* indicates the current file format (currently 2).
+``Py_MARSHAL_VERSION`` indicates the current file format (currently 2).
.. c:function:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
@@ -25,12 +25,16 @@ unmarshalling. Version 2 uses a binary format for floating point numbers.
the least-significant 32 bits of *value*; regardless of the size of the
native :c:type:`long` type. *version* indicates the file format.
+ This function can fail, in which case it sets the error indicator.
+ Use :c:func:`PyErr_Occurred` to check for that.
.. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)
Marshal a Python object, *value*, to *file*.
*version* indicates the file format.
+ This function can fail, in which case it sets the error indicator.
+ Use :c:func:`PyErr_Occurred` to check for that.
.. c:function:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version)
@@ -40,12 +44,6 @@ unmarshalling. Version 2 uses a binary format for floating point numbers.
The following functions allow marshalled values to be read back in.
-XXX What about error detection? It appears that reading past the end of the
-file will always result in a negative numeric value (where that's relevant),
-but it's not clear that negative values won't be handled properly when there's
-no error. What's the right way to tell? Should only non-negative values be
-written using these routines?
-
.. c:function:: long PyMarshal_ReadLongFromFile(FILE *file)
@@ -53,7 +51,8 @@ written using these routines?
for reading. Only a 32-bit value can be read in using this function,
regardless of the native size of :c:type:`long`.
- On error, raise an exception and return ``-1``.
+ On error, sets the appropriate exception (:exc:`EOFError`) and returns
+ ``-1``.
.. c:function:: int PyMarshal_ReadShortFromFile(FILE *file)
@@ -62,7 +61,8 @@ written using these routines?
for reading. Only a 16-bit value can be read in using this function,
regardless of the native size of :c:type:`short`.
- On error, raise an exception and return ``-1``.
+ On error, sets the appropriate exception (:exc:`EOFError`) and returns
+ ``-1``.
.. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file)
@@ -70,8 +70,8 @@ written using these routines?
Return a Python object from the data stream in a :c:type:`FILE\*` opened for
reading.
- On error, sets the appropriate exception (:exc:`EOFError` or
- :exc:`TypeError`) and returns *NULL*.
+ On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
+ or :exc:`TypeError`) and returns ``NULL``.
.. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file)
@@ -84,8 +84,8 @@ written using these routines?
file. Only use these variant if you are certain that you won't be reading
anything else from the file.
- On error, sets the appropriate exception (:exc:`EOFError` or
- :exc:`TypeError`) and returns *NULL*.
+ On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
+ or :exc:`TypeError`) and returns ``NULL``.
.. c:function:: PyObject* PyMarshal_ReadObjectFromString(const char *data, Py_ssize_t len)
@@ -93,6 +93,6 @@ written using these routines?
Return a Python object from the data stream in a byte buffer
containing *len* bytes pointed to by *data*.
- On error, sets the appropriate exception (:exc:`EOFError` or
- :exc:`TypeError`) and returns *NULL*.
+ On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
+ or :exc:`TypeError`) and returns ``NULL``.
diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst
index 2af0c46d451f05..f4c94c4f3ce8d9 100644
--- a/Doc/c-api/memory.rst
+++ b/Doc/c-api/memory.rst
@@ -35,7 +35,7 @@ operate within the bounds of the private heap.
It is important to understand that the management of the Python heap is
performed by the interpreter itself and that the user has no control over it,
-even if she regularly manipulates object pointers to memory blocks inside that
+even if they regularly manipulate object pointers to memory blocks inside that
heap. The allocation of heap space for Python objects and other internal
buffers is performed on demand by the Python memory manager through the Python/C
API functions listed in this document.
@@ -67,7 +67,7 @@ example::
In this example, the memory request for the I/O buffer is handled by the C
library allocator. The Python memory manager is involved only in the allocation
-of the string object returned as a result.
+of the bytes object returned as a result.
In most situations, however, it is recommended to allocate memory from the
Python heap specifically because the latter is under control of the Python
@@ -110,9 +110,9 @@ zero bytes.
.. c:function:: void* PyMem_RawMalloc(size_t n)
Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
- allocated memory, or *NULL* if the request fails.
+ allocated memory, or ``NULL`` if the request fails.
- Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as
+ Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
if ``PyMem_RawMalloc(1)`` had been called instead. The memory will not have
been initialized in any way.
@@ -120,11 +120,11 @@ zero bytes.
.. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the
+ a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
- non-*NULL* pointer if possible, as if ``PyMem_RawCalloc(1, 1)`` had been
+ non-``NULL`` pointer if possible, as if ``PyMem_RawCalloc(1, 1)`` had been
called instead.
.. versionadded:: 3.5
@@ -135,15 +135,15 @@ zero bytes.
Resizes the memory block pointed to by *p* to *n* bytes. The contents will
be unchanged to the minimum of the old and the new sizes.
- If *p* is *NULL*, the call is equivalent to ``PyMem_RawMalloc(n)``; else if
+ If *p* is ``NULL``, the call is equivalent to ``PyMem_RawMalloc(n)``; else if
*n* is equal to zero, the memory block is resized but is not freed, and the
- returned pointer is non-*NULL*.
+ returned pointer is non-``NULL``.
- Unless *p* is *NULL*, it must have been returned by a previous call to
+ Unless *p* is ``NULL``, it must have been returned by a previous call to
:c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc` or
:c:func:`PyMem_RawCalloc`.
- If the request fails, :c:func:`PyMem_RawRealloc` returns *NULL* and *p*
+ If the request fails, :c:func:`PyMem_RawRealloc` returns ``NULL`` and *p*
remains a valid pointer to the previous memory area.
@@ -154,7 +154,7 @@ zero bytes.
:c:func:`PyMem_RawCalloc`. Otherwise, or if ``PyMem_RawFree(p)`` has been
called before, undefined behavior occurs.
- If *p* is *NULL*, no operation is performed.
+ If *p* is ``NULL``, no operation is performed.
.. _memoryinterface:
@@ -181,9 +181,9 @@ The :ref:`default memory allocator ` uses the
.. c:function:: void* PyMem_Malloc(size_t n)
Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
- allocated memory, or *NULL* if the request fails.
+ allocated memory, or ``NULL`` if the request fails.
- Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as
+ Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
if ``PyMem_Malloc(1)`` had been called instead. The memory will not have
been initialized in any way.
@@ -191,11 +191,11 @@ The :ref:`default memory allocator ` uses the
.. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the
+ a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
- non-*NULL* pointer if possible, as if ``PyMem_Calloc(1, 1)`` had been called
+ non-``NULL`` pointer if possible, as if ``PyMem_Calloc(1, 1)`` had been called
instead.
.. versionadded:: 3.5
@@ -206,14 +206,14 @@ The :ref:`default memory allocator ` uses the
Resizes the memory block pointed to by *p* to *n* bytes. The contents will be
unchanged to the minimum of the old and the new sizes.
- If *p* is *NULL*, the call is equivalent to ``PyMem_Malloc(n)``; else if *n*
+ If *p* is ``NULL``, the call is equivalent to ``PyMem_Malloc(n)``; else if *n*
is equal to zero, the memory block is resized but is not freed, and the
- returned pointer is non-*NULL*.
+ returned pointer is non-``NULL``.
- Unless *p* is *NULL*, it must have been returned by a previous call to
+ Unless *p* is ``NULL``, it must have been returned by a previous call to
:c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc` or :c:func:`PyMem_Calloc`.
- If the request fails, :c:func:`PyMem_Realloc` returns *NULL* and *p* remains
+ If the request fails, :c:func:`PyMem_Realloc` returns ``NULL`` and *p* remains
a valid pointer to the previous memory area.
@@ -224,7 +224,7 @@ The :ref:`default memory allocator ` uses the
:c:func:`PyMem_Calloc`. Otherwise, or if ``PyMem_Free(p)`` has been called
before, undefined behavior occurs.
- If *p* is *NULL*, no operation is performed.
+ If *p* is ``NULL``, no operation is performed.
The following type-oriented macros are provided for convenience. Note that
*TYPE* refers to any C type.
@@ -241,7 +241,7 @@ The following type-oriented macros are provided for convenience. Note that
Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n *
sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE\*`. On return,
- *p* will be a pointer to the new memory area, or *NULL* in the event of
+ *p* will be a pointer to the new memory area, or ``NULL`` in the event of
failure.
This is a C preprocessor macro; *p* is always reassigned. Save the original
@@ -283,9 +283,9 @@ The :ref:`default object allocator ` uses the
.. c:function:: void* PyObject_Malloc(size_t n)
Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
- allocated memory, or *NULL* if the request fails.
+ allocated memory, or ``NULL`` if the request fails.
- Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as
+ Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
if ``PyObject_Malloc(1)`` had been called instead. The memory will not have
been initialized in any way.
@@ -293,11 +293,11 @@ The :ref:`default object allocator ` uses the
.. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize)
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
- a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the
+ a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the
request fails. The memory is initialized to zeros.
Requesting zero elements or elements of size zero bytes returns a distinct
- non-*NULL* pointer if possible, as if ``PyObject_Calloc(1, 1)`` had been called
+ non-``NULL`` pointer if possible, as if ``PyObject_Calloc(1, 1)`` had been called
instead.
.. versionadded:: 3.5
@@ -308,14 +308,14 @@ The :ref:`default object allocator ` uses the
Resizes the memory block pointed to by *p* to *n* bytes. The contents will be
unchanged to the minimum of the old and the new sizes.
- If *p* is *NULL*, the call is equivalent to ``PyObject_Malloc(n)``; else if *n*
+ If *p* is ``NULL``, the call is equivalent to ``PyObject_Malloc(n)``; else if *n*
is equal to zero, the memory block is resized but is not freed, and the
- returned pointer is non-*NULL*.
+ returned pointer is non-``NULL``.
- Unless *p* is *NULL*, it must have been returned by a previous call to
+ Unless *p* is ``NULL``, it must have been returned by a previous call to
:c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc` or :c:func:`PyObject_Calloc`.
- If the request fails, :c:func:`PyObject_Realloc` returns *NULL* and *p* remains
+ If the request fails, :c:func:`PyObject_Realloc` returns ``NULL`` and *p* remains
a valid pointer to the previous memory area.
@@ -326,7 +326,7 @@ The :ref:`default object allocator ` uses the
:c:func:`PyObject_Calloc`. Otherwise, or if ``PyObject_Free(p)`` has been called
before, undefined behavior occurs.
- If *p* is *NULL*, no operation is performed.
+ If *p* is ``NULL``, no operation is performed.
.. _default-memory-allocators:
@@ -342,7 +342,7 @@ Configuration Name PyMem_RawMalloc PyMem
Release build ``"pymalloc"`` ``malloc`` ``pymalloc`` ``pymalloc``
Debug build ``"pymalloc_debug"`` ``malloc`` + debug ``pymalloc`` + debug ``pymalloc`` + debug
Release build, without pymalloc ``"malloc"`` ``malloc`` ``malloc`` ``malloc``
-Release build, without pymalloc ``"malloc_debug"`` ``malloc`` + debug ``malloc`` + debug ``malloc`` + debug
+Debug build, without pymalloc ``"malloc_debug"`` ``malloc`` + debug ``malloc`` + debug ``malloc`` + debug
=============================== ==================== ================== ===================== ====================
Legend:
@@ -424,7 +424,7 @@ Customize Memory Allocators
Set the memory block allocator of the specified domain.
- The new allocator must return a distinct non-NULL pointer when requesting
+ The new allocator must return a distinct non-``NULL`` pointer when requesting
zero bytes.
For the :c:data:`PYMEM_DOMAIN_RAW` domain, the allocator must be
@@ -440,8 +440,9 @@ Customize Memory Allocators
Setup hooks to detect bugs in the Python memory allocator functions.
- Newly allocated memory is filled with the byte ``0xCB``, freed memory is
- filled with the byte ``0xDB``.
+ Newly allocated memory is filled with the byte ``0xCD`` (``CLEANBYTE``),
+ freed memory is filled with the byte ``0xDD`` (``DEADBYTE``). Memory blocks
+ are surrounded by "forbidden bytes" (``FORBIDDENBYTE``: byte ``0xFD``).
Runtime checks:
@@ -471,6 +472,12 @@ Customize Memory Allocators
if the GIL is held when functions of :c:data:`PYMEM_DOMAIN_OBJ` and
:c:data:`PYMEM_DOMAIN_MEM` domains are called.
+ .. versionchanged:: 3.7.3
+ Byte patterns ``0xCB`` (``CLEANBYTE``), ``0xDB`` (``DEADBYTE``) and
+ ``0xFB`` (``FORBIDDENBYTE``) have been replaced with ``0xCD``, ``0xDD``
+ and ``0xFD`` to use the same values than Windows CRT debug ``malloc()``
+ and ``free()``.
+
.. _pymalloc:
@@ -526,16 +533,16 @@ tracemalloc C API
.. versionadded:: 3.7
-.. c:function: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size)
+.. c:function:: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size)
Track an allocated memory block in the :mod:`tracemalloc` module.
- Return 0 on success, return ``-1`` on error (failed to allocate memory to
+ Return ``0`` on success, return ``-1`` on error (failed to allocate memory to
store the trace). Return ``-2`` if tracemalloc is disabled.
If memory block is already tracked, update the existing trace.
-.. c:function: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
+.. c:function:: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
Untrack an allocated memory block in the :mod:`tracemalloc` module.
Do nothing if the block was not tracked.
diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst
index 9f6bfd751ade5e..0fcd96dacfa6a6 100644
--- a/Doc/c-api/memoryview.rst
+++ b/Doc/c-api/memoryview.rst
@@ -57,7 +57,7 @@ any other object.
.. c:function:: Py_buffer *PyMemoryView_GET_BASE(PyObject *mview)
Return either a pointer to the exporting object that the memoryview is based
- on or *NULL* if the memoryview has been created by one of the functions
+ on or ``NULL`` if the memoryview has been created by one of the functions
:c:func:`PyMemoryView_FromMemory` or :c:func:`PyMemoryView_FromBuffer`.
*mview* **must** be a memoryview instance.
diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst
index 7a2a84fe110dcf..c08bc32ac83a24 100644
--- a/Doc/c-api/method.rst
+++ b/Doc/c-api/method.rst
@@ -21,7 +21,7 @@ to bind a :c:data:`PyCFunction` to a class object. It replaces the former call
.. c:function:: int PyInstanceMethod_Check(PyObject *o)
Return true if *o* is an instance method object (has type
- :c:data:`PyInstanceMethod_Type`). The parameter must not be *NULL*.
+ :c:data:`PyInstanceMethod_Type`). The parameter must not be ``NULL``.
.. c:function:: PyObject* PyInstanceMethod_New(PyObject *func)
@@ -64,14 +64,14 @@ no longer available.
.. c:function:: int PyMethod_Check(PyObject *o)
Return true if *o* is a method object (has type :c:data:`PyMethod_Type`). The
- parameter must not be *NULL*.
+ parameter must not be ``NULL``.
.. c:function:: PyObject* PyMethod_New(PyObject *func, PyObject *self)
Return a new method object, with *func* being any callable object and *self*
the instance the method should be bound. *func* is the function that will
- be called when the method is called. *self* must not be *NULL*.
+ be called when the method is called. *self* must not be ``NULL``.
.. c:function:: PyObject* PyMethod_Function(PyObject *meth)
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 7efab28af724aa..c85bf17ca3d51e 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -61,7 +61,7 @@ Module Objects
Return the dictionary object that implements *module*'s namespace; this object
is the same as the :attr:`~object.__dict__` attribute of the module object.
If *module* is not a module object (or a subtype of a module object),
- :exc:`SystemError` is raised and *NULL* is returned.
+ :exc:`SystemError` is raised and ``NULL`` is returned.
It is recommended extensions use other :c:func:`PyModule_\*` and
:c:func:`PyObject_\*` functions rather than directly manipulate a module's
@@ -75,7 +75,7 @@ Module Objects
single: SystemError (built-in exception)
Return *module*'s :attr:`__name__` value. If the module does not provide one,
- or if it is not a string, :exc:`SystemError` is raised and *NULL* is returned.
+ or if it is not a string, :exc:`SystemError` is raised and ``NULL`` is returned.
.. versionadded:: 3.3
@@ -88,14 +88,14 @@ Module Objects
.. c:function:: void* PyModule_GetState(PyObject *module)
Return the "state" of the module, that is, a pointer to the block of memory
- allocated at module creation time, or *NULL*. See
+ allocated at module creation time, or ``NULL``. See
:c:member:`PyModuleDef.m_size`.
.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module)
Return a pointer to the :c:type:`PyModuleDef` struct from which the module was
- created, or *NULL* if the module wasn't created from a definition.
+ created, or ``NULL`` if the module wasn't created from a definition.
.. c:function:: PyObject* PyModule_GetFilenameObject(PyObject *module)
@@ -106,7 +106,7 @@ Module Objects
Return the name of the file from which *module* was loaded using *module*'s
:attr:`__file__` attribute. If this is not defined, or if it is not a
- unicode string, raise :exc:`SystemError` and return *NULL*; otherwise return
+ unicode string, raise :exc:`SystemError` and return ``NULL``; otherwise return
a reference to a Unicode object.
.. versionadded:: 3.2
@@ -153,7 +153,7 @@ or request "multi-phase initialization" by returning the definition struct itsel
.. c:member:: const char *m_doc
Docstring for the module; usually a docstring variable created with
- :c:func:`PyDoc_STRVAR` is used.
+ :c:macro:`PyDoc_STRVAR` is used.
.. c:member:: Py_ssize_t m_size
@@ -178,17 +178,17 @@ or request "multi-phase initialization" by returning the definition struct itsel
.. c:member:: PyMethodDef* m_methods
A pointer to a table of module-level functions, described by
- :c:type:`PyMethodDef` values. Can be *NULL* if no functions are present.
+ :c:type:`PyMethodDef` values. Can be ``NULL`` if no functions are present.
.. c:member:: PyModuleDef_Slot* m_slots
An array of slot definitions for multi-phase initialization, terminated by
a ``{0, NULL}`` entry.
- When using single-phase initialization, *m_slots* must be *NULL*.
+ When using single-phase initialization, *m_slots* must be ``NULL``.
.. versionchanged:: 3.5
- Prior to version 3.5, this member was always set to *NULL*,
+ Prior to version 3.5, this member was always set to ``NULL``,
and was defined as:
.. c:member:: inquiry m_reload
@@ -196,17 +196,23 @@ or request "multi-phase initialization" by returning the definition struct itsel
.. c:member:: traverseproc m_traverse
A traversal function to call during GC traversal of the module object, or
- *NULL* if not needed.
+ ``NULL`` if not needed. This function may be called before module state
+ is allocated (:c:func:`PyModule_GetState()` may return `NULL`),
+ and before the :c:member:`Py_mod_exec` function is executed.
.. c:member:: inquiry m_clear
A clear function to call during GC clearing of the module object, or
- *NULL* if not needed.
+ ``NULL`` if not needed. This function may be called before module state
+ is allocated (:c:func:`PyModule_GetState()` may return `NULL`),
+ and before the :c:member:`Py_mod_exec` function is executed.
.. c:member:: freefunc m_free
- A function to call during deallocation of the module object, or *NULL* if
- not needed.
+ A function to call during deallocation of the module object, or ``NULL`` if
+ not needed. This function may be called before module state
+ is allocated (:c:func:`PyModule_GetState()` may return `NULL`),
+ and before the :c:member:`Py_mod_exec` function is executed.
Single-phase initialization
...........................
@@ -272,7 +278,7 @@ instance must be initialized with the following function:
Ensures a module definition is a properly initialized Python object that
correctly reports its type and reference count.
- Returns *def* cast to ``PyObject*``, or *NULL* if an error occurred.
+ Returns *def* cast to ``PyObject*``, or ``NULL`` if an error occurred.
.. versionadded:: 3.5
@@ -305,7 +311,7 @@ The available slot types are:
The function receives a :py:class:`~importlib.machinery.ModuleSpec`
instance, as defined in :PEP:`451`, and the module definition.
It should return a new module object, or set an error
- and return *NULL*.
+ and return ``NULL``.
This function should be kept minimal. In particular, it should not
call arbitrary Python code, as trying to import the same module again may
@@ -324,7 +330,7 @@ The available slot types are:
:c:type:`PyModule_Type`. Any type can be used, as long as it supports
setting and getting import-related attributes.
However, only ``PyModule_Type`` instances may be returned if the
- ``PyModuleDef`` has non-*NULL* ``m_traverse``, ``m_clear``,
+ ``PyModuleDef`` has non-``NULL`` ``m_traverse``, ``m_clear``,
``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``.
.. c:var:: Py_mod_exec
@@ -388,7 +394,7 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and
.. c:function:: int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)
- Add the functions from the *NULL* terminated *functions* array to *module*.
+ Add the functions from the ``NULL`` terminated *functions* array to *module*.
Refer to the :c:type:`PyMethodDef` documentation for details on individual
entries (due to the lack of a shared module namespace, module level
"functions" implemented in C typically receive the module as their first
@@ -411,7 +417,22 @@ state:
Add an object to *module* as *name*. This is a convenience function which can
be used from the module's initialization function. This steals a reference to
- *value*. Return ``-1`` on error, ``0`` on success.
+ *value* on success. Return ``-1`` on error, ``0`` on success.
+
+ .. note::
+
+ Unlike other functions that steal references, ``PyModule_AddObject()`` only
+ decrements the reference count of *value* **on success**.
+
+ This means that its return value must be checked, and calling code must
+ :c:func:`Py_DECREF` *value* manually on error. Example usage::
+
+ Py_INCREF(spam);
+ if (PyModule_AddObject(module, "spam", spam) < 0) {
+ Py_DECREF(module);
+ Py_DECREF(spam);
+ return NULL;
+ }
.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
@@ -424,7 +445,7 @@ state:
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`` on error, ``0`` on success.
.. c:function:: int PyModule_AddIntMacro(PyObject *module, macro)
@@ -455,7 +476,7 @@ since multiple such modules can be created from a single definition.
Returns the module object that was created from *def* for the current interpreter.
This method requires that the module object has been attached to the interpreter state with
:c:func:`PyState_AddModule` beforehand. In case the corresponding module object is not
- found or has not been attached to the interpreter state yet, it returns *NULL*.
+ found or has not been attached to the interpreter state yet, it returns ``NULL``.
.. c:function:: int PyState_AddModule(PyObject *module, PyModuleDef *def)
@@ -464,10 +485,21 @@ since multiple such modules can be created from a single definition.
Only effective on modules created using single-phase initialization.
+ Python calls ``PyState_AddModule`` automatically after importing a module,
+ so it is unnecessary (but harmless) to call it from module initialization
+ code. An explicit call is needed only if the module's own init code
+ subsequently calls ``PyState_FindModule``.
+ The function is mainly intended for implementing alternative import
+ mechanisms (either by calling it directly, or by referring to its
+ implementation for details of the required state updates).
+
+ Return 0 on success or -1 on failure.
+
.. 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.
.. versionadded:: 3.3
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
index 3c7605a67fa226..82c43670ecc2e0 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -14,25 +14,25 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Add(PyObject *o1, PyObject *o2)
- Returns the result of adding *o1* and *o2*, or *NULL* on failure. This is the
+ Returns the result of adding *o1* and *o2*, or ``NULL`` on failure. This is the
equivalent of the Python expression ``o1 + o2``.
.. c:function:: PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2)
- Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. This is
+ Returns the result of subtracting *o2* from *o1*, or ``NULL`` on failure. This is
the equivalent of the Python expression ``o1 - o2``.
.. c:function:: PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2)
- Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. This is
+ Returns the result of multiplying *o1* and *o2*, or ``NULL`` on failure. This is
the equivalent of the Python expression ``o1 * o2``.
.. c:function:: PyObject* PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2)
- Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on
+ Returns the result of matrix multiplication on *o1* and *o2*, or ``NULL`` on
failure. This is the equivalent of the Python expression ``o1 @ o2``.
.. versionadded:: 3.5
@@ -40,14 +40,14 @@ Number Protocol
.. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2)
- Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is
+ Return the floor of *o1* divided by *o2*, or ``NULL`` on failure. This is
equivalent to the "classic" division of integers.
.. c:function:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2)
Return a reasonable approximation for the mathematical value of *o1* divided by
- *o2*, or *NULL* on failure. The return value is "approximate" because binary
+ *o2*, or ``NULL`` on failure. The return value is "approximate" because binary
floating point numbers are approximate; it is not possible to represent all real
numbers in base two. This function can return a floating point value when
passed two integers.
@@ -55,7 +55,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2)
- Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. This is
+ Returns the remainder of dividing *o1* by *o2*, or ``NULL`` on failure. This is
the equivalent of the Python expression ``o1 % o2``.
@@ -63,7 +63,7 @@ Number Protocol
.. index:: builtin: divmod
- See the built-in function :func:`divmod`. Returns *NULL* on failure. This is
+ See the built-in function :func:`divmod`. Returns ``NULL`` on failure. This is
the equivalent of the Python expression ``divmod(o1, o2)``.
@@ -71,21 +71,21 @@ Number Protocol
.. index:: builtin: pow
- See the built-in function :func:`pow`. Returns *NULL* on failure. This is the
+ See the built-in function :func:`pow`. Returns ``NULL`` on failure. This is the
equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional.
- If *o3* is to be ignored, pass :c:data:`Py_None` in its place (passing *NULL* for
+ If *o3* is to be ignored, pass :c:data:`Py_None` in its place (passing ``NULL`` for
*o3* would cause an illegal memory access).
.. c:function:: PyObject* PyNumber_Negative(PyObject *o)
- Returns the negation of *o* on success, or *NULL* on failure. This is the
+ Returns the negation of *o* on success, or ``NULL`` on failure. This is the
equivalent of the Python expression ``-o``.
.. c:function:: PyObject* PyNumber_Positive(PyObject *o)
- Returns *o* on success, or *NULL* on failure. This is the equivalent of the
+ Returns *o* on success, or ``NULL`` on failure. This is the equivalent of the
Python expression ``+o``.
@@ -93,70 +93,70 @@ Number Protocol
.. index:: builtin: abs
- Returns the absolute value of *o*, or *NULL* on failure. This is the equivalent
+ Returns the absolute value of *o*, or ``NULL`` on failure. This is the equivalent
of the Python expression ``abs(o)``.
.. c:function:: PyObject* PyNumber_Invert(PyObject *o)
- Returns the bitwise negation of *o* on success, or *NULL* on failure. This is
+ Returns the bitwise negation of *o* on success, or ``NULL`` on failure. This is
the equivalent of the Python expression ``~o``.
.. c:function:: PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2)
- Returns the result of left shifting *o1* by *o2* on success, or *NULL* on
+ Returns the result of left shifting *o1* by *o2* on success, or ``NULL`` on
failure. This is the equivalent of the Python expression ``o1 << o2``.
.. c:function:: PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2)
- Returns the result of right shifting *o1* by *o2* on success, or *NULL* on
+ Returns the result of right shifting *o1* by *o2* on success, or ``NULL`` on
failure. This is the equivalent of the Python expression ``o1 >> o2``.
.. c:function:: PyObject* PyNumber_And(PyObject *o1, PyObject *o2)
- Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure.
+ Returns the "bitwise and" of *o1* and *o2* on success and ``NULL`` on failure.
This is the equivalent of the Python expression ``o1 & o2``.
.. c:function:: PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2)
- Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on
+ Returns the "bitwise exclusive or" of *o1* by *o2* on success, or ``NULL`` on
failure. This is the equivalent of the Python expression ``o1 ^ o2``.
.. c:function:: PyObject* PyNumber_Or(PyObject *o1, PyObject *o2)
- Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure.
+ Returns the "bitwise or" of *o1* and *o2* on success, or ``NULL`` on failure.
This is the equivalent of the Python expression ``o1 | o2``.
.. c:function:: PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2)
- Returns the result of adding *o1* and *o2*, or *NULL* on failure. The operation
+ Returns the result of adding *o1* and *o2*, or ``NULL`` on failure. The operation
is done *in-place* when *o1* supports it. This is the equivalent of the Python
statement ``o1 += o2``.
.. c:function:: PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2)
- Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. The
+ Returns the result of subtracting *o2* from *o1*, or ``NULL`` on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 -= o2``.
.. c:function:: PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2)
- Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. The
+ Returns the result of multiplying *o1* and *o2*, or ``NULL`` on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 *= o2``.
.. c:function:: PyObject* PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2)
- Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on
+ Returns the result of matrix multiplication on *o1* and *o2*, or ``NULL`` on
failure. The operation is done *in-place* when *o1* supports it. This is
the equivalent of the Python statement ``o1 @= o2``.
@@ -165,7 +165,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2)
- Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure.
+ Returns the mathematical floor of dividing *o1* by *o2*, or ``NULL`` on failure.
The operation is done *in-place* when *o1* supports it. This is the equivalent
of the Python statement ``o1 //= o2``.
@@ -173,7 +173,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2)
Return a reasonable approximation for the mathematical value of *o1* divided by
- *o2*, or *NULL* on failure. The return value is "approximate" because binary
+ *o2*, or ``NULL`` on failure. The return value is "approximate" because binary
floating point numbers are approximate; it is not possible to represent all real
numbers in base two. This function can return a floating point value when
passed two integers. The operation is done *in-place* when *o1* supports it.
@@ -181,7 +181,7 @@ Number Protocol
.. c:function:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2)
- Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. The
+ Returns the remainder of dividing *o1* by *o2*, or ``NULL`` on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 %= o2``.
@@ -190,44 +190,44 @@ Number Protocol
.. index:: builtin: pow
- See the built-in function :func:`pow`. Returns *NULL* on failure. The operation
+ See the built-in function :func:`pow`. Returns ``NULL`` on failure. The operation
is done *in-place* when *o1* supports it. This is the equivalent of the Python
statement ``o1 **= o2`` when o3 is :c:data:`Py_None`, or an in-place variant of
``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :c:data:`Py_None`
- in its place (passing *NULL* for *o3* would cause an illegal memory access).
+ in its place (passing ``NULL`` for *o3* would cause an illegal memory access).
.. c:function:: PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2)
- Returns the result of left shifting *o1* by *o2* on success, or *NULL* on
+ Returns the result of left shifting *o1* by *o2* on success, or ``NULL`` on
failure. The operation is done *in-place* when *o1* supports it. This is the
equivalent of the Python statement ``o1 <<= o2``.
.. c:function:: PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2)
- Returns the result of right shifting *o1* by *o2* on success, or *NULL* on
+ Returns the result of right shifting *o1* by *o2* on success, or ``NULL`` on
failure. The operation is done *in-place* when *o1* supports it. This is the
equivalent of the Python statement ``o1 >>= o2``.
.. c:function:: PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2)
- Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. The
+ Returns the "bitwise and" of *o1* and *o2* on success and ``NULL`` on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 &= o2``.
.. c:function:: PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2)
- Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on
+ Returns the "bitwise exclusive or" of *o1* by *o2* on success, or ``NULL`` on
failure. The operation is done *in-place* when *o1* supports it. This is the
equivalent of the Python statement ``o1 ^= o2``.
.. c:function:: PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2)
- Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. The
+ Returns the "bitwise or" of *o1* and *o2* on success, or ``NULL`` on failure. The
operation is done *in-place* when *o1* supports it. This is the equivalent of
the Python statement ``o1 |= o2``.
@@ -236,7 +236,7 @@ Number Protocol
.. index:: builtin: int
- Returns the *o* converted to an integer object on success, or *NULL* on
+ Returns the *o* converted to an integer object on success, or ``NULL`` on
failure. This is the equivalent of the Python expression ``int(o)``.
@@ -244,13 +244,13 @@ Number Protocol
.. index:: builtin: float
- Returns the *o* converted to a float object on success, or *NULL* on failure.
+ Returns the *o* converted to a float object on success, or ``NULL`` on failure.
This is the equivalent of the Python expression ``float(o)``.
.. c:function:: PyObject* PyNumber_Index(PyObject *o)
- Returns the *o* converted to a Python int on success or *NULL* with a
+ Returns the *o* converted to a Python int on success or ``NULL`` with a
:exc:`TypeError` exception raised on failure.
@@ -271,12 +271,13 @@ Number Protocol
If *o* can be converted to a Python int but the attempt to
convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the
*exc* argument is the type of exception that will be raised (usually
- :exc:`IndexError` or :exc:`OverflowError`). If *exc* is *NULL*, then the
- exception is cleared and the value is clipped to *PY_SSIZE_T_MIN* for a negative
- integer or *PY_SSIZE_T_MAX* for a positive integer.
+ :exc:`IndexError` or :exc:`OverflowError`). If *exc* is ``NULL``, then the
+ exception is cleared and the value is clipped to ``PY_SSIZE_T_MIN`` for a negative
+ integer or ``PY_SSIZE_T_MAX`` for a positive integer.
.. c:function:: int PyIndex_Check(PyObject *o)
Returns ``1`` if *o* is an index integer (has the nb_index slot of the
tp_as_number structure filled in), and ``0`` otherwise.
+ This function always succeeds.
diff --git a/Doc/c-api/objbuffer.rst b/Doc/c-api/objbuffer.rst
index e7f4fde00256db..3572564b13e9b3 100644
--- a/Doc/c-api/objbuffer.rst
+++ b/Doc/c-api/objbuffer.rst
@@ -39,7 +39,11 @@ an object, and :c:func:`PyBuffer_Release` when the buffer view can be released.
.. c:function:: int PyObject_CheckReadBuffer(PyObject *o)
Returns ``1`` if *o* supports the single-segment readable buffer interface.
- Otherwise returns ``0``.
+ Otherwise returns ``0``. This function always succeeds.
+
+ Note that this function tries to get and release a buffer, and exceptions
+ which occur while calling corresponding functions will get suppressed.
+ To get error reporting use :c:func:`PyObject_GetBuffer()` instead.
.. c:function:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index 754dedc1c60370..179efc4286f86c 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -33,6 +33,10 @@ Object Protocol
is equivalent to the Python expression ``hasattr(o, attr_name)``. This function
always succeeds.
+ Note that exceptions which occur while calling :meth:`__getattr__` and
+ :meth:`__getattribute__` methods will get suppressed.
+ To get error reporting use :c:func:`PyObject_GetAttr()` instead.
+
.. c:function:: int PyObject_HasAttrString(PyObject *o, const char *attr_name)
@@ -40,18 +44,23 @@ Object Protocol
is equivalent to the Python expression ``hasattr(o, attr_name)``. This function
always succeeds.
+ Note that exceptions which occur while calling :meth:`__getattr__` and
+ :meth:`__getattribute__` methods and creating a temporary string object
+ will get suppressed.
+ To get error reporting use :c:func:`PyObject_GetAttrString()` instead.
+
.. c:function:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name)
Retrieve an attribute named *attr_name* from object *o*. Returns the attribute
- value on success, or *NULL* on failure. This is the equivalent of the Python
+ value on success, or ``NULL`` on failure. This is the equivalent of the Python
expression ``o.attr_name``.
.. c:function:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name)
Retrieve an attribute named *attr_name* from object *o*. Returns the attribute
- value on success, or *NULL* on failure. This is the equivalent of the Python
+ value on success, or ``NULL`` on failure. This is the equivalent of the Python
expression ``o.attr_name``.
@@ -72,7 +81,7 @@ Object Protocol
return ``0`` on success. This is the equivalent of the Python statement
``o.attr_name = v``.
- If *v* is *NULL*, the attribute is deleted, however this feature is
+ If *v* is ``NULL``, the attribute is deleted, however this feature is
deprecated in favour of using :c:func:`PyObject_DelAttr`.
@@ -83,7 +92,7 @@ Object Protocol
return ``0`` on success. This is the equivalent of the Python statement
``o.attr_name = v``.
- If *v* is *NULL*, the attribute is deleted, however this feature is
+ If *v* is ``NULL``, the attribute is deleted, however this feature is
deprecated in favour of using :c:func:`PyObject_DelAttrString`.
@@ -119,7 +128,7 @@ Object Protocol
.. versionadded:: 3.3
-.. c:function:: int PyObject_GenericSetDict(PyObject *o, void *context)
+.. c:function:: int PyObject_GenericSetDict(PyObject *o, PyObject *value, void *context)
A generic implementation for the setter of a ``__dict__`` descriptor. This
implementation does not allow the dictionary to be deleted.
@@ -134,7 +143,7 @@ Object Protocol
:const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``,
``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. This is the equivalent of
the Python expression ``o1 op o2``, where ``op`` is the operator corresponding
- to *opid*. Returns the value of the comparison on success, or *NULL* on failure.
+ to *opid*. Returns the value of the comparison on success, or ``NULL`` on failure.
.. c:function:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)
@@ -156,7 +165,7 @@ Object Protocol
.. index:: builtin: repr
Compute a string representation of object *o*. Returns the string
- representation on success, *NULL* on failure. This is the equivalent of the
+ representation on success, ``NULL`` on failure. This is the equivalent of the
Python expression ``repr(o)``. Called by the :func:`repr` built-in function.
.. versionchanged:: 3.4
@@ -179,7 +188,7 @@ Object Protocol
.. c:function:: PyObject* PyObject_Str(PyObject *o)
Compute a string representation of object *o*. Returns the string
- representation on success, *NULL* on failure. This is the equivalent of the
+ representation on success, ``NULL`` on failure. This is the equivalent of the
Python expression ``str(o)``. Called by the :func:`str` built-in function
and, therefore, by the :func:`print` function.
@@ -191,7 +200,7 @@ Object Protocol
.. index:: builtin: bytes
- Compute a bytes representation of object *o*. *NULL* is returned on
+ Compute a bytes representation of object *o*. ``NULL`` is returned on
failure and a bytes object on success. This is equivalent to the Python
expression ``bytes(o)``, when *o* is not an integer. Unlike ``bytes(o)``,
a TypeError is raised when *o* is an integer instead of a zero-initialized
@@ -249,10 +258,11 @@ Object Protocol
Call a callable Python object *callable*, with arguments given by the
tuple *args*, and named arguments given by the dictionary *kwargs*.
- *args* must not be *NULL*, use an empty tuple if no arguments are needed.
- If no named arguments are needed, *kwargs* can be *NULL*.
+ *args* must not be ``NULL``, use an empty tuple if no arguments are needed.
+ If no named arguments are needed, *kwargs* can be ``NULL``.
- Returns the result of the call on success, or *NULL* on failure.
+ Return the result of the call on success, or raise an exception and return
+ ``NULL`` on failure.
This is the equivalent of the Python expression:
``callable(*args, **kwargs)``.
@@ -261,9 +271,10 @@ Object Protocol
.. c:function:: PyObject* PyObject_CallObject(PyObject *callable, PyObject *args)
Call a callable Python object *callable*, with arguments given by the
- tuple *args*. If no arguments are needed, then *args* can be *NULL*.
+ tuple *args*. If no arguments are needed, then *args* can be ``NULL``.
- Returns the result of the call on success, or *NULL* on failure.
+ Return the result of the call on success, or raise an exception and return
+ ``NULL`` on failure.
This is the equivalent of the Python expression: ``callable(*args)``.
@@ -272,9 +283,10 @@ Object Protocol
Call a callable Python object *callable*, with a variable number of C arguments.
The C arguments are described using a :c:func:`Py_BuildValue` style format
- string. The format can be *NULL*, indicating that no arguments are provided.
+ string. The format can be ``NULL``, indicating that no arguments are provided.
- Returns the result of the call on success, or *NULL* on failure.
+ Return the result of the call on success, or raise an exception and return
+ ``NULL`` on failure.
This is the equivalent of the Python expression: ``callable(*args)``.
@@ -291,9 +303,10 @@ Object Protocol
arguments. The C arguments are described by a :c:func:`Py_BuildValue` format
string that should produce a tuple.
- The format can be *NULL*, indicating that no arguments are provided.
+ The format can be ``NULL``, indicating that no arguments are provided.
- Returns the result of the call on success, or *NULL* on failure.
+ Return the result of the call on success, or raise an exception and return
+ ``NULL`` on failure.
This is the equivalent of the Python expression:
``obj.name(arg1, arg2, ...)``.
@@ -309,9 +322,10 @@ Object Protocol
Call a callable Python object *callable*, with a variable number of
:c:type:`PyObject\*` arguments. The arguments are provided as a variable number
- of parameters followed by *NULL*.
+ of parameters followed by ``NULL``.
- Returns the result of the call on success, or *NULL* on failure.
+ Return the result of the call on success, or raise an exception and return
+ ``NULL`` on failure.
This is the equivalent of the Python expression:
``callable(arg1, arg2, ...)``.
@@ -322,8 +336,10 @@ Object Protocol
Calls a method of the Python object *obj*, where the name of the method is given as a
Python string object in *name*. It is called with a variable number of
:c:type:`PyObject\*` arguments. The arguments are provided as a variable number
- of parameters followed by *NULL*. Returns the result of the call on success, or
- *NULL* on failure.
+ of parameters followed by ``NULL``.
+
+ Return the result of the call on success, or raise an exception and return
+ ``NULL`` on failure.
.. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
@@ -364,8 +380,8 @@ Object Protocol
.. index:: builtin: type
- When *o* is non-*NULL*, returns a type object corresponding to the object type
- of object *o*. On failure, raises :exc:`SystemError` and returns *NULL*. This
+ When *o* is non-``NULL``, returns a type object corresponding to the object type
+ of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``. This
is equivalent to the Python expression ``type(o)``. This function increments the
reference count of the return value. There's really no reason to use this
function instead of the common expression ``o->ob_type``, which returns a
@@ -376,11 +392,11 @@ Object Protocol
.. c:function:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type)
Return true if the object *o* is of type *type* or a subtype of *type*. Both
- parameters must be non-*NULL*.
+ parameters must be non-``NULL``.
-.. c:function:: Py_ssize_t PyObject_Length(PyObject *o)
- Py_ssize_t PyObject_Size(PyObject *o)
+.. c:function:: Py_ssize_t PyObject_Size(PyObject *o)
+ Py_ssize_t PyObject_Length(PyObject *o)
.. index:: builtin: len
@@ -401,7 +417,7 @@ Object Protocol
.. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key)
- Return element of *o* corresponding to the object *key* or *NULL* on failure.
+ Return element of *o* corresponding to the object *key* or ``NULL`` on failure.
This is the equivalent of the Python expression ``o[key]``.
@@ -414,22 +430,22 @@ Object Protocol
.. c:function:: int PyObject_DelItem(PyObject *o, PyObject *key)
- Delete the mapping for *key* from *o*. Returns ``-1`` on failure. This is the
- equivalent of the Python statement ``del o[key]``.
+ Remove the mapping for the object *key* from the object *o*. Return ``-1``
+ on failure. This is equivalent to the Python statement ``del o[key]``.
.. c:function:: PyObject* PyObject_Dir(PyObject *o)
This is equivalent to the Python expression ``dir(o)``, returning a (possibly
- empty) list of strings appropriate for the object argument, or *NULL* if there
- was an error. If the argument is *NULL*, this is like the Python ``dir()``,
+ empty) list of strings appropriate for the object argument, or ``NULL`` if there
+ was an error. If the argument is ``NULL``, this is like the Python ``dir()``,
returning the names of the current locals; in this case, if no execution frame
- is active then *NULL* is returned but :c:func:`PyErr_Occurred` will return false.
+ is active then ``NULL`` is returned but :c:func:`PyErr_Occurred` will return false.
.. c:function:: PyObject* PyObject_GetIter(PyObject *o)
This is equivalent to the Python expression ``iter(o)``. It returns a new
iterator for the object argument, or the object itself if the object is already
- an iterator. Raises :exc:`TypeError` and returns *NULL* if the object cannot be
+ an iterator. Raises :exc:`TypeError` and returns ``NULL`` if the object cannot be
iterated.
diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst
index 4f512ecdbe9fb0..1479db42d70f4c 100644
--- a/Doc/c-api/refcounting.rst
+++ b/Doc/c-api/refcounting.rst
@@ -13,22 +13,22 @@ objects.
.. c:function:: void Py_INCREF(PyObject *o)
- Increment the reference count for object *o*. The object must not be *NULL*; if
- you aren't sure that it isn't *NULL*, use :c:func:`Py_XINCREF`.
+ Increment the reference count for object *o*. The object must not be ``NULL``; if
+ you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`.
.. c:function:: void Py_XINCREF(PyObject *o)
- Increment the reference count for object *o*. The object may be *NULL*, in
+ Increment the reference count for object *o*. The object may be ``NULL``, in
which case the macro has no effect.
.. c:function:: void Py_DECREF(PyObject *o)
- Decrement the reference count for object *o*. The object must not be *NULL*; if
- you aren't sure that it isn't *NULL*, use :c:func:`Py_XDECREF`. If the reference
+ Decrement the reference count for object *o*. The object must not be ``NULL``; if
+ you aren't sure that it isn't ``NULL``, use :c:func:`Py_XDECREF`. If the reference
count reaches zero, the object's type's deallocation function (which must not be
- *NULL*) is invoked.
+ ``NULL``) is invoked.
.. warning::
@@ -44,18 +44,18 @@ objects.
.. c:function:: void Py_XDECREF(PyObject *o)
- Decrement the reference count for object *o*. The object may be *NULL*, in
+ Decrement the reference count for object *o*. The object may be ``NULL``, in
which case the macro has no effect; otherwise the effect is the same as for
:c:func:`Py_DECREF`, and the same warning applies.
.. c:function:: void Py_CLEAR(PyObject *o)
- Decrement the reference count for object *o*. The object may be *NULL*, in
+ Decrement the reference count for object *o*. The object may be ``NULL``, in
which case the macro has no effect; otherwise the effect is the same as for
- :c:func:`Py_DECREF`, except that the argument is also set to *NULL*. The warning
+ :c:func:`Py_DECREF`, except that the argument is also set to ``NULL``. The warning
for :c:func:`Py_DECREF` does not apply with respect to the object passed because
- the macro carefully uses a temporary variable and sets the argument to *NULL*
+ the macro carefully uses a temporary variable and sets the argument to ``NULL``
before decrementing its reference count.
It is a good idea to use this macro whenever decrementing the value of a
diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst
index 96893652f730cc..cb9a8f8a180cf1 100644
--- a/Doc/c-api/reflection.rst
+++ b/Doc/c-api/reflection.rst
@@ -14,18 +14,18 @@ Reflection
.. c:function:: PyObject* PyEval_GetLocals()
Return a dictionary of the local variables in the current execution frame,
- or *NULL* if no frame is currently executing.
+ or ``NULL`` if no frame is currently executing.
.. c:function:: PyObject* PyEval_GetGlobals()
Return a dictionary of the global variables in the current execution frame,
- or *NULL* if no frame is currently executing.
+ or ``NULL`` if no frame is currently executing.
.. c:function:: PyFrameObject* PyEval_GetFrame()
- Return the current thread state's frame, which is *NULL* if no frame is
+ Return the current thread state's frame, which is ``NULL`` if no frame is
currently executing.
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index f1825f079be474..7db618a1004fa1 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -9,7 +9,10 @@ Sequence Protocol
.. c:function:: int PySequence_Check(PyObject *o)
Return ``1`` if the object provides sequence protocol, and ``0`` otherwise.
- This function always succeeds.
+ Note that it returns ``1`` for Python classes with a :meth:`__getitem__`
+ method unless they are :class:`dict` subclasses since in general case it
+ is impossible to determine what the type of keys it supports. This
+ function always succeeds.
.. c:function:: Py_ssize_t PySequence_Size(PyObject *o)
@@ -17,46 +20,45 @@ Sequence Protocol
.. index:: builtin: len
- Returns the number of objects in sequence *o* on success, and ``-1`` on failure.
- For objects that do not provide sequence protocol, this is equivalent to the
- Python expression ``len(o)``.
+ Returns the number of objects in sequence *o* on success, and ``-1`` on
+ failure. This is equivalent to the Python expression ``len(o)``.
.. c:function:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2)
- Return the concatenation of *o1* and *o2* on success, and *NULL* on failure.
+ Return the concatenation of *o1* and *o2* on success, and ``NULL`` on failure.
This is the equivalent of the Python expression ``o1 + o2``.
.. c:function:: PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count)
- Return the result of repeating sequence object *o* *count* times, or *NULL* on
+ Return the result of repeating sequence object *o* *count* times, or ``NULL`` on
failure. This is the equivalent of the Python expression ``o * count``.
.. c:function:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2)
- Return the concatenation of *o1* and *o2* on success, and *NULL* on failure.
+ Return the concatenation of *o1* and *o2* on success, and ``NULL`` on failure.
The operation is done *in-place* when *o1* supports it. This is the equivalent
of the Python expression ``o1 += o2``.
.. c:function:: PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
- Return the result of repeating sequence object *o* *count* times, or *NULL* on
+ Return the result of repeating sequence object *o* *count* times, or ``NULL`` on
failure. The operation is done *in-place* when *o* supports it. This is the
equivalent of the Python expression ``o *= count``.
.. c:function:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i)
- Return the *i*\ th element of *o*, or *NULL* on failure. This is the equivalent of
+ Return the *i*\ th element of *o*, or ``NULL`` on failure. This is the equivalent of
the Python expression ``o[i]``.
.. c:function:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2)
- Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on
+ Return the slice of sequence object *o* between *i1* and *i2*, or ``NULL`` on
failure. This is the equivalent of the Python expression ``o[i1:i2]``.
@@ -67,7 +69,7 @@ Sequence Protocol
is the equivalent of the Python statement ``o[i] = v``. This function *does
not* steal a reference to *v*.
- If *v* is *NULL*, the element is deleted, however this feature is
+ If *v* is ``NULL``, the element is deleted, however this feature is
deprecated in favour of using :c:func:`PySequence_DelItem`.
@@ -112,7 +114,7 @@ Sequence Protocol
.. c:function:: PyObject* PySequence_List(PyObject *o)
Return a list object with the same contents as the sequence or iterable *o*,
- or *NULL* on failure. The returned list is guaranteed to be new. This is
+ or ``NULL`` on failure. The returned list is guaranteed to be new. This is
equivalent to the Python expression ``list(o)``.
@@ -120,30 +122,46 @@ Sequence Protocol
.. index:: builtin: tuple
- Return a tuple object with the same contents as the arbitrary sequence *o* or
- *NULL* on failure. If *o* is a tuple, a new reference will be returned,
+ Return a tuple object with the same contents as the sequence or iterable *o*,
+ or ``NULL`` on failure. If *o* is a tuple, a new reference will be returned,
otherwise a tuple will be constructed with the appropriate contents. This is
equivalent to the Python expression ``tuple(o)``.
.. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m)
- Return the sequence *o* as a list, unless it is already a tuple or list, in
- which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access
- the members of the result. Returns *NULL* on failure. If the object is not
- a sequence, raises :exc:`TypeError` with *m* as the message text.
+ Return the sequence or iterable *o* as an object usable by the other
+ ``PySequence_Fast*`` family of functions. If the object is not a sequence or
+ iterable, raises :exc:`TypeError` with *m* as the message text. Returns
+ ``NULL`` on failure.
+
+ The ``PySequence_Fast*`` functions are thus named because they assume
+ *o* is a :c:type:`PyTupleObject` or a :c:type:`PyListObject` and access
+ the data fields of *o* directly.
+
+ As a CPython implementation detail, if *o* is already a sequence or list, it
+ will be returned.
+
+
+.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
+
+ Returns the length of *o*, assuming that *o* was returned by
+ :c:func:`PySequence_Fast` and that *o* is not ``NULL``. The size can also be
+ gotten by calling :c:func:`PySequence_Size` on *o*, but
+ :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a
+ list or tuple.
.. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)
Return the *i*\ th element of *o*, assuming that *o* was returned by
- :c:func:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds.
+ :c:func:`PySequence_Fast`, *o* is not ``NULL``, and that *i* is within bounds.
.. c:function:: PyObject** PySequence_Fast_ITEMS(PyObject *o)
Return the underlying array of PyObject pointers. Assumes that *o* was returned
- by :c:func:`PySequence_Fast` and *o* is not *NULL*.
+ by :c:func:`PySequence_Fast` and *o* is not ``NULL``.
Note, if a list gets resized, the reallocation may relocate the items array.
So, only use the underlying array pointer in contexts where the sequence
@@ -152,16 +170,7 @@ Sequence Protocol
.. c:function:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)
- Return the *i*\ th element of *o* or *NULL* on failure. Macro form of
+ Return the *i*\ th element of *o* or ``NULL`` on failure. Faster form of
:c:func:`PySequence_GetItem` but without checking that
:c:func:`PySequence_Check` on *o* is true and without adjustment for negative
indices.
-
-
-.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
-
- Returns the length of *o*, assuming that *o* was returned by
- :c:func:`PySequence_Fast` and that *o* is not *NULL*. The size can also be
- gotten by calling :c:func:`PySequence_Size` on *o*, but
- :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list
- or tuple.
diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst
index 64b6dde3b7482e..34ee077b88de9e 100644
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -80,8 +80,8 @@ the constructor functions work with any iterable Python object.
.. c:function:: PyObject* PySet_New(PyObject *iterable)
Return a new :class:`set` containing objects returned by the *iterable*. The
- *iterable* may be *NULL* to create a new empty set. Return the new set on
- success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is not
+ *iterable* may be ``NULL`` to create a new empty set. Return the new set on
+ success or ``NULL`` on failure. Raise :exc:`TypeError` if *iterable* is not
actually iterable. The constructor is also useful for copying a set
(``c=set(s)``).
@@ -89,8 +89,8 @@ the constructor functions work with any iterable Python object.
.. c:function:: PyObject* PyFrozenSet_New(PyObject *iterable)
Return a new :class:`frozenset` containing objects returned by the *iterable*.
- The *iterable* may be *NULL* to create a new empty frozenset. Return the new
- set on success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is
+ The *iterable* may be ``NULL`` to create a new empty frozenset. Return the new
+ set on success or ``NULL`` on failure. Raise :exc:`TypeError` if *iterable* is
not actually iterable.
@@ -149,7 +149,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
.. c:function:: PyObject* PySet_Pop(PyObject *set)
Return a new reference to an arbitrary object in the *set*, and removes the
- object from the *set*. Return *NULL* on failure. Raise :exc:`KeyError` if the
+ object from the *set*. Return ``NULL`` on failure. Raise :exc:`KeyError` if the
set is empty. Raise a :exc:`SystemError` if *set* is not an instance of
:class:`set` or its subtype.
diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst
index 8ad9a29b256ebc..c72ab04cbc543a 100644
--- a/Doc/c-api/slice.rst
+++ b/Doc/c-api/slice.rst
@@ -14,15 +14,15 @@ Slice Objects
.. c:function:: int PySlice_Check(PyObject *ob)
- Return true if *ob* is a slice object; *ob* must not be *NULL*.
+ Return true if *ob* is a slice object; *ob* must not be ``NULL``.
.. c:function:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
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
+ 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
the new object could not be allocated.
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index 797b9045fa8edc..0aa1ef026c14e5 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -106,18 +106,28 @@ the definition of all other Python objects.
Type of the functions used to implement most Python callables in C.
Functions of this type take two :c:type:`PyObject\*` parameters and return
- one such value. If the return value is *NULL*, an exception shall have
- been set. If not *NULL*, the return value is interpreted as the return
+ one such value. If the return value is ``NULL``, an exception shall have
+ been set. If not ``NULL``, the return value is interpreted as the return
value of the function as exposed in Python. The function must return a new
reference.
.. c:type:: PyCFunctionWithKeywords
- Type of the functions used to implement Python callables in C that take
- keyword arguments: they take three :c:type:`PyObject\*` parameters and return
- one such value. See :c:type:`PyCFunction` above for the meaning of the return
- value.
+ Type of the functions used to implement Python callables in C
+ with signature :const:`METH_VARARGS | METH_KEYWORDS`.
+
+
+.. c:type:: _PyCFunctionFast
+
+ Type of the functions used to implement Python callables in C
+ with signature :const:`METH_FASTCALL`.
+
+
+.. c:type:: _PyCFunctionFastWithKeywords
+
+ Type of the functions used to implement Python callables in C
+ with signature :const:`METH_FASTCALL | METH_KEYWORDS`.
.. c:type:: PyMethodDef
@@ -149,10 +159,11 @@ specific C type of the *self* object.
The :attr:`ml_flags` field is a bitfield which can include the following flags.
The individual flags indicate either a calling convention or a binding
-convention. Of the calling convention flags, only :const:`METH_VARARGS` and
-:const:`METH_KEYWORDS` can be combined. Any of the calling convention flags
-can be combined with a binding flag.
+convention.
+There are four basic calling conventions for positional arguments
+and two of them can be combined with :const:`METH_KEYWORDS` to support
+also keyword arguments. So there are a total of 6 calling conventions:
.. data:: METH_VARARGS
@@ -164,13 +175,41 @@ can be combined with a binding flag.
using :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_UnpackTuple`.
-.. data:: METH_KEYWORDS
+.. data:: METH_VARARGS | METH_KEYWORDS
Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`.
- The function expects three parameters: *self*, *args*, and a dictionary of
- all the keyword arguments. The flag must be combined with
- :const:`METH_VARARGS`, and the parameters are typically processed using
- :c:func:`PyArg_ParseTupleAndKeywords`.
+ The function expects three parameters: *self*, *args*, *kwargs* where
+ *kwargs* is a dictionary of all the keyword arguments or possibly ``NULL``
+ if there are no keyword arguments. The parameters are typically processed
+ using :c:func:`PyArg_ParseTupleAndKeywords`.
+
+
+.. data:: METH_FASTCALL
+
+ Fast calling convention supporting only positional arguments.
+ The methods have the type :c:type:`_PyCFunctionFast`.
+ The first parameter is *self*, the second parameter is a C array
+ of :c:type:`PyObject\*` values indicating the arguments and the third
+ parameter is the number of arguments (the length of the array).
+
+ This is not part of the :ref:`limited API `.
+
+ .. versionadded:: 3.7
+
+
+.. data:: METH_FASTCALL | METH_KEYWORDS
+
+ Extension of :const:`METH_FASTCALL` supporting also keyword arguments,
+ with methods of type :c:type:`_PyCFunctionFastWithKeywords`.
+ Keyword arguments are passed the same way as in the vectorcall protocol:
+ there is an additional fourth :c:type:`PyObject\*` parameter
+ which is a tuple representing the names of the keyword arguments
+ or possibly ``NULL`` if there are no keywords. The values of the keyword
+ arguments are stored in the *args* array, after the positional arguments.
+
+ This is not part of the :ref:`limited API `.
+
+ .. versionadded:: 3.7
.. data:: METH_NOARGS
@@ -179,7 +218,7 @@ can be combined with a binding flag.
they are listed with the :const:`METH_NOARGS` flag. They need to be of type
:c:type:`PyCFunction`. The first parameter is typically named *self* and will
hold a reference to the module or object instance. In all cases the second
- parameter will be *NULL*.
+ parameter will be ``NULL``.
.. data:: METH_O
@@ -210,7 +249,7 @@ method.
.. index:: builtin: staticmethod
- The method will be passed *NULL* as the first parameter rather than an
+ The method will be passed ``NULL`` as the first parameter rather than an
instance of the type. This is used to create *static methods*, similar to
what is created when using the :func:`staticmethod` built-in function.
@@ -284,7 +323,7 @@ definition with the same method name.
=============== ==================
:c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX` differ in that
- :c:macro:`T_OBJECT` returns ``None`` if the member is *NULL* and
+ :c:macro:`T_OBJECT` returns ``None`` if the member is ``NULL`` and
:c:macro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use
:c:macro:`T_OBJECT_EX` over :c:macro:`T_OBJECT` because :c:macro:`T_OBJECT_EX`
handles use of the :keyword:`del` statement on that attribute more correctly
@@ -292,8 +331,9 @@ definition with the same method name.
:attr:`flags` can be ``0`` for write and read access or :c:macro:`READONLY` for
read-only access. Using :c:macro:`T_STRING` for :attr:`type` implies
- :c:macro:`READONLY`. Only :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX`
- members can be deleted. (They are set to *NULL*).
+ :c:macro:`READONLY`. :c:macro:`T_STRING` data is interpreted as UTF-8.
+ Only :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX`
+ members can be deleted. (They are set to ``NULL``).
.. c:type:: PyGetSetDef
@@ -324,7 +364,7 @@ definition with the same method name.
typedef PyObject *(*getter)(PyObject *, void *);
- It should return a new reference on success or *NULL* with a set exception
+ It should return a new reference on success or ``NULL`` with a set exception
on failure.
``set`` functions take two :c:type:`PyObject\*` parameters (the instance and
@@ -332,5 +372,5 @@ definition with the same method name.
typedef int (*setter)(PyObject *, PyObject *, void *);
- In case the attribute should be deleted the second parameter is *NULL*.
+ In case the attribute should be deleted the second parameter is ``NULL``.
Should return ``0`` on success or ``-1`` with a set exception on failure.
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index e4da96c493cd88..e1715bccf55a53 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -22,7 +22,7 @@ Operating System Utilities
Return true (nonzero) if the standard I/O file *fp* with name *filename* is
deemed interactive. This is the case for files for which ``isatty(fileno(fp))``
is true. If the global flag :c:data:`Py_InteractiveFlag` is true, this function
- also returns true if the *filename* pointer is *NULL* or if the name is equal to
+ also returns true if the *filename* pointer is ``NULL`` or if the name is equal to
one of the strings ``''`` or ``'???'``.
@@ -194,27 +194,35 @@ accessible to C code. They all work with the current interpreter thread's
.. c:function:: PyObject *PySys_GetObject(const char *name)
- Return the object *name* from the :mod:`sys` module or *NULL* if it does
+ Return the object *name* from the :mod:`sys` module or ``NULL`` if it does
not exist, without setting an exception.
.. c:function:: int PySys_SetObject(const char *name, PyObject *v)
- Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which
+ Set *name* in the :mod:`sys` module to *v* unless *v* is ``NULL``, in which
case *name* is deleted from the sys module. Returns ``0`` on success, ``-1``
on error.
.. c:function:: void PySys_ResetWarnOptions()
- Reset :data:`sys.warnoptions` to an empty list.
+ Reset :data:`sys.warnoptions` to an empty list. This function may be
+ called prior to :c:func:`Py_Initialize`.
.. c:function:: void PySys_AddWarnOption(const wchar_t *s)
- Append *s* to :data:`sys.warnoptions`.
+ Append *s* to :data:`sys.warnoptions`. This function must be called prior
+ to :c:func:`Py_Initialize` in order to affect the warnings filter list.
.. c:function:: void PySys_AddWarnOptionUnicode(PyObject *unicode)
Append *unicode* to :data:`sys.warnoptions`.
+ Note: this function is not currently usable from outside the CPython
+ implementation, as it must be called prior to the implicit import of
+ :mod:`warnings` in :c:func:`Py_Initialize` to be effective, but can't be
+ called until enough of the runtime has been initialized to permit the
+ creation of Unicode objects.
+
.. c:function:: void PySys_SetPath(const wchar_t *path)
Set :data:`sys.path` to a list object of paths found in *path* which should
@@ -260,14 +268,15 @@ accessible to C code. They all work with the current interpreter thread's
.. c:function:: void PySys_AddXOption(const wchar_t *s)
Parse *s* as a set of :option:`-X` options and add them to the current
- options mapping as returned by :c:func:`PySys_GetXOptions`.
+ options mapping as returned by :c:func:`PySys_GetXOptions`. This function
+ may be called prior to :c:func:`Py_Initialize`.
.. versionadded:: 3.2
.. c:function:: PyObject *PySys_GetXOptions()
Return the current dictionary of :option:`-X` options, similarly to
- :data:`sys._xoptions`. On error, *NULL* is returned and an exception is
+ :data:`sys._xoptions`. On error, ``NULL`` is returned and an exception is
set.
.. versionadded:: 3.2
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index a66832cfa43492..b7d4b7bb496469 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -33,12 +33,12 @@ Tuple Objects
.. c:function:: PyObject* PyTuple_New(Py_ssize_t len)
- Return a new tuple object of size *len*, or *NULL* on failure.
+ Return a new tuple object of size *len*, or ``NULL`` on failure.
.. c:function:: PyObject* PyTuple_Pack(Py_ssize_t n, ...)
- Return a new tuple object of size *n*, or *NULL* on failure. The tuple values
+ Return a new tuple object of size *n*, or ``NULL`` on failure. The tuple values
are initialized to the subsequent *n* C arguments pointing to Python objects.
``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``.
@@ -50,14 +50,14 @@ Tuple Objects
.. c:function:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p)
- Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple;
+ Return the size of the tuple *p*, which must be non-``NULL`` and point to a tuple;
no error checking is performed.
.. c:function:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos)
Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is
- out of bounds, return *NULL* and sets an :exc:`IndexError` exception.
+ out of bounds, return ``NULL`` and set an :exc:`IndexError` exception.
.. c:function:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos)
@@ -67,18 +67,21 @@ Tuple Objects
.. c:function:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high)
- Take a slice of the tuple pointed to by *p* from *low* to *high* and return it
- as a new tuple.
+ Return the slice of the tuple pointed to by *p* between *low* and *high*,
+ or ``NULL`` on failure. This is the equivalent of the Python expression
+ ``p[low:high]``. Indexing from the end of the list is not supported.
.. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)
Insert a reference to object *o* at position *pos* of the tuple pointed to by
- *p*. Return ``0`` on success.
+ *p*. Return ``0`` on success. If *pos* is out of bounds, return ``-1``
+ and set an :exc:`IndexError` exception.
.. note::
- This function "steals" a reference to *o*.
+ This function "steals" a reference to *o* and discards a reference to
+ an item already in the tuple at the affected position.
.. c:function:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
@@ -88,7 +91,10 @@ Tuple Objects
.. note::
- This function "steals" a reference to *o*.
+ This macro "steals" a reference to *o*, and, unlike
+ :c:func:`PyTuple_SetItem`, does *not* discard a reference to any item that
+ is being replaced; any reference in the tuple at position *pos* will be
+ leaked.
.. c:function:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize)
@@ -101,7 +107,7 @@ Tuple Objects
only more efficiently. Returns ``0`` on success. Client code should never
assume that the resulting value of ``*p`` will be the same as before calling
this function. If the object referenced by ``*p`` is replaced, the original
- ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and
+ ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to ``NULL``, and
raises :exc:`MemoryError` or :exc:`SystemError`.
@@ -141,20 +147,20 @@ type.
Contains the meta information of a struct sequence type to create.
- +-------------------+------------------------------+------------------------------------+
- | Field | C Type | Meaning |
- +===================+==============================+====================================+
- | ``name`` | ``const char *`` | name of the struct sequence type |
- +-------------------+------------------------------+------------------------------------+
- | ``doc`` | ``const char *`` | pointer to docstring for the type |
- | | | or NULL to omit |
- +-------------------+------------------------------+------------------------------------+
- | ``fields`` | ``PyStructSequence_Field *`` | pointer to *NULL*-terminated array |
- | | | with field names of the new type |
- +-------------------+------------------------------+------------------------------------+
- | ``n_in_sequence`` | ``int`` | number of fields visible to the |
- | | | Python side (if used as tuple) |
- +-------------------+------------------------------+------------------------------------+
+ +-------------------+------------------------------+--------------------------------------+
+ | Field | C Type | Meaning |
+ +===================+==============================+======================================+
+ | ``name`` | ``const char *`` | name of the struct sequence type |
+ +-------------------+------------------------------+--------------------------------------+
+ | ``doc`` | ``const char *`` | pointer to docstring for the type |
+ | | | or ``NULL`` to omit |
+ +-------------------+------------------------------+--------------------------------------+
+ | ``fields`` | ``PyStructSequence_Field *`` | pointer to ``NULL``-terminated array |
+ | | | with field names of the new type |
+ +-------------------+------------------------------+--------------------------------------+
+ | ``n_in_sequence`` | ``int`` | number of fields visible to the |
+ | | | Python side (if used as tuple) |
+ +-------------------+------------------------------+--------------------------------------+
.. c:type:: PyStructSequence_Field
@@ -164,16 +170,16 @@ type.
:attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which
field of the struct sequence is described.
- +-----------+------------------+--------------------------------------+
- | Field | C Type | Meaning |
- +===========+==================+======================================+
- | ``name`` | ``const char *`` | name for the field or *NULL* to end |
- | | | the list of named fields, set to |
- | | | PyStructSequence_UnnamedField to |
- | | | leave unnamed |
- +-----------+------------------+--------------------------------------+
- | ``doc`` | ``const char *`` | field docstring or *NULL* to omit |
- +-----------+------------------+--------------------------------------+
+ +-----------+------------------+-----------------------------------------+
+ | Field | C Type | Meaning |
+ +===========+==================+=========================================+
+ | ``name`` | ``const char *`` | name for the field or ``NULL`` to end |
+ | | | the list of named fields, set to |
+ | | | :c:data:`PyStructSequence_UnnamedField` |
+ | | | to leave unnamed |
+ +-----------+------------------+-----------------------------------------+
+ | ``doc`` | ``const char *`` | field docstring or ``NULL`` to omit |
+ +-----------+------------------+-----------------------------------------+
.. c:var:: char* PyStructSequence_UnnamedField
@@ -209,7 +215,7 @@ type.
This function "steals" a reference to *o*.
-.. c:function:: PyObject* PyStructSequence_SET_ITEM(PyObject *p, Py_ssize_t *pos, PyObject *o)
+.. c:function:: void PyStructSequence_SET_ITEM(PyObject *p, Py_ssize_t *pos, PyObject *o)
Macro equivalent of :c:func:`PyStructSequence_SetItem`.
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index 60c5e73960b3a1..5a3d749a0a2589 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -35,7 +35,7 @@ Type Objects
Clear the internal lookup cache. Return the current version tag.
-.. c:function:: long PyType_GetFlags(PyTypeObject* type)
+.. c:function:: unsigned long PyType_GetFlags(PyTypeObject* type)
Return the :c:member:`~PyTypeObject.tp_flags` member of *type*. This function is primarily
meant for use with `Py_LIMITED_API`; the individual flag bits are
@@ -44,6 +44,9 @@ Type Objects
.. versionadded:: 3.2
+ .. versionchanged:: 3.4
+ The return type is now ``unsigned long`` rather than ``long``.
+
.. c:function:: void PyType_Modified(PyTypeObject *type)
@@ -78,7 +81,7 @@ Type Objects
Generic handler for the :c:member:`~PyTypeObject.tp_alloc` slot of a type object. Use
Python's default memory allocation mechanism to allocate a new instance and
- initialize all its contents to *NULL*.
+ initialize all its contents to ``NULL``.
.. c:function:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
@@ -107,7 +110,7 @@ Type Objects
.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot)
Return the function pointer stored in the given slot. If the
- result is *NULL*, this indicates that either the slot is *NULL*,
+ result is ``NULL``, this indicates that either the slot is ``NULL``,
or that the function was called with invalid parameters.
Callers will typically cast the result pointer into the appropriate
function type.
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 3bdf45ad9b61f7..057187e4ba8460 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -43,8 +43,8 @@ type objects) *must* have the :attr:`ob_size` field.
PyObject* PyObject._ob_prev
These fields are only present when the macro ``Py_TRACE_REFS`` is defined.
- Their initialization to *NULL* is taken care of by the ``PyObject_HEAD_INIT``
- macro. For statically allocated objects, these fields always remain *NULL*.
+ Their initialization to ``NULL`` is taken care of by the ``PyObject_HEAD_INIT``
+ macro. For statically allocated objects, these fields always remain ``NULL``.
For dynamically allocated objects, these two fields are used to link the object
into a doubly-linked list of *all* live objects on the heap. This could be used
for various debugging purposes; currently the only use is to print the objects
@@ -71,7 +71,7 @@ type objects) *must* have the :attr:`ob_size` field.
argument to the ``PyObject_HEAD_INIT`` macro, and its value should normally be
``&PyType_Type``. However, for dynamically loadable extension modules that must
be usable on Windows (at least), the compiler complains that this is not a valid
- initializer. Therefore, the convention is to pass *NULL* to the
+ initializer. Therefore, the convention is to pass ``NULL`` to the
``PyObject_HEAD_INIT`` macro and to initialize this field explicitly at the
start of the module's initialization function, before doing anything else. This
is typically done like this::
@@ -79,7 +79,7 @@ type objects) *must* have the :attr:`ob_size` field.
Foo_Type.ob_type = &PyType_Type;
This should be done before any instances of the type are created.
- :c:func:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so,
+ :c:func:`PyType_Ready` checks if :attr:`ob_type` is ``NULL``, and if so,
initializes it to the :attr:`ob_type` field of the base class.
:c:func:`PyType_Ready` will not change this field if it is non-zero.
@@ -205,7 +205,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype
inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when
- the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both *NULL*.
+ the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both ``NULL``.
.. c:member:: setattrfunc PyTypeObject.tp_setattr
@@ -218,10 +218,10 @@ type objects) *must* have the :attr:`ob_size` field.
PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v);
- The *v* argument is set to *NULL* to delete the attribute.
+ The *v* argument is set to ``NULL`` to delete the attribute.
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype
inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when
- the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*.
+ the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both ``NULL``.
.. c:member:: PyAsyncMethods* tp_as_async
@@ -310,13 +310,13 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes together with
:c:member:`~PyTypeObject.tp_richcompare`: a subtype inherits both of
:c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash`, when the subtype's
- :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both *NULL*.
+ :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both ``NULL``.
.. c:member:: ternaryfunc PyTypeObject.tp_call
An optional pointer to a function that implements calling the object. This
- should be *NULL* if the object is not callable. The signature is the same as
+ should be ``NULL`` if the object is not callable. The signature is the same as
for :c:func:`PyObject_Call`.
This field is inherited by subtypes.
@@ -350,7 +350,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattr`: a subtype
inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when
- the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both *NULL*.
+ the subtype's :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` are both ``NULL``.
.. c:member:: setattrofunc PyTypeObject.tp_setattro
@@ -358,13 +358,13 @@ type objects) *must* have the :attr:`ob_size` field.
An optional pointer to the function for setting and deleting attributes.
The signature is the same as for :c:func:`PyObject_SetAttr`, but setting
- *v* to *NULL* to delete an attribute must be supported. It is usually
+ *v* to ``NULL`` to delete an attribute must be supported. It is usually
convenient to set this field to :c:func:`PyObject_GenericSetAttr`, which
implements the normal way of setting object attributes.
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattr`: a subtype
inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when
- the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*.
+ the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both ``NULL``.
.. c:member:: PyBufferProcs* PyTypeObject.tp_as_buffer
@@ -385,7 +385,7 @@ type objects) *must* have the :attr:`ob_size` field.
:c:member:`~PyTypeObject.tp_as_number`, :c:member:`~PyTypeObject.tp_as_sequence`, :c:member:`~PyTypeObject.tp_as_mapping`, and
:c:member:`~PyTypeObject.tp_as_buffer`) that were historically not always present are valid; if
such a flag bit is clear, the type fields it guards must not be accessed and
- must be considered to have a zero or *NULL* value instead.
+ must be considered to have a zero or ``NULL`` value instead.
Inheritance of this field is complicated. Most flag bits are inherited
individually, i.e. if the base type has a flag bit set, the subtype inherits
@@ -396,7 +396,7 @@ type objects) *must* have the :attr:`ob_size` field.
the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields, i.e. if the
:const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the
:c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have
- *NULL* values.
+ ``NULL`` values.
The following bit masks are currently defined; these can be ORed together using
the ``|`` operator to form the value of the :c:member:`~PyTypeObject.tp_flags` field. The macro
@@ -496,7 +496,7 @@ type objects) *must* have the :attr:`ob_size` field.
The :c:member:`~PyTypeObject.tp_traverse` pointer is used by the garbage collector to detect
reference cycles. A typical implementation of a :c:member:`~PyTypeObject.tp_traverse` function
simply calls :c:func:`Py_VISIT` on each of the instance's members that are Python
- objects. For example, this is function :c:func:`local_traverse` from the
+ objects that the instance owns. For example, this is function :c:func:`local_traverse` from the
:mod:`_thread` extension module::
static int
@@ -510,12 +510,24 @@ type objects) *must* have the :attr:`ob_size` field.
Note that :c:func:`Py_VISIT` is called only on those members that can participate
in reference cycles. Although there is also a ``self->key`` member, it can only
- be *NULL* or a Python string and therefore cannot be part of a reference cycle.
+ be ``NULL`` or a Python string and therefore cannot be part of a reference cycle.
On the other hand, even if you know a member can never be part of a cycle, as a
debugging aid you may want to visit it anyway just so the :mod:`gc` module's
:func:`~gc.get_referents` function will include it.
+ .. warning::
+ When implementing :c:member:`~PyTypeObject.tp_traverse`, only the members
+ that the instance *owns* (by having strong references to them) must be
+ visited. For instance, if an object supports weak references via the
+ :c:member:`~PyTypeObject.tp_weaklist` slot, the pointer supporting
+ the linked list (what *tp_weaklist* points to) must **not** be
+ visited as the instance does not directly own the weak references to itself
+ (the weakreference list is there to support the weak reference machinery,
+ but the instance has no strong reference to the elements inside it, as they
+ are allowed to be removed even if the instance is still alive).
+
+
Note that :c:func:`Py_VISIT` requires the *visit* and *arg* parameters to
:c:func:`local_traverse` to have these specific names; don't name them just
anything.
@@ -543,7 +555,7 @@ type objects) *must* have the :attr:`ob_size` field.
Implementations of :c:member:`~PyTypeObject.tp_clear` should drop the instance's references to
those of its members that may be Python objects, and set its pointers to those
- members to *NULL*, as in the following example::
+ members to ``NULL``, as in the following example::
static int
local_clear(localobject *self)
@@ -557,12 +569,12 @@ type objects) *must* have the :attr:`ob_size` field.
The :c:func:`Py_CLEAR` macro should be used, because clearing references is
delicate: the reference to the contained object must not be decremented until
- after the pointer to the contained object is set to *NULL*. This is because
+ after the pointer to the contained object is set to ``NULL``. This is because
decrementing the reference count may cause the contained object to become trash,
triggering a chain of reclamation activity that may include invoking arbitrary
Python code (due to finalizers, or weakref callbacks, associated with the
contained object). If it's possible for such code to reference *self* again,
- it's important that the pointer to the contained object be *NULL* at that time,
+ it's important that the pointer to the contained object be ``NULL`` at that time,
so that *self* knows the contained object can no longer be used. The
:c:func:`Py_CLEAR` macro performs the operations in a safe order.
@@ -602,7 +614,7 @@ type objects) *must* have the :attr:`ob_size` field.
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_hash`:
a subtype inherits :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` when
the subtype's :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both
- *NULL*.
+ ``NULL``.
The following constants are defined to be used as the third argument for
:c:member:`~PyTypeObject.tp_richcompare` and for :c:func:`PyObject_RichCompare`:
@@ -647,7 +659,7 @@ type objects) *must* have the :attr:`ob_size` field.
reference list head (ignoring the GC header, if present); this offset is used by
:c:func:`PyObject_ClearWeakRefs` and the :c:func:`PyWeakref_\*` functions. The
instance structure needs to include a field of type :c:type:`PyObject\*` which is
- initialized to *NULL*.
+ initialized to ``NULL``.
Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for
weak references to the type object itself.
@@ -685,9 +697,9 @@ type objects) *must* have the :attr:`ob_size` field.
.. c:member:: iternextfunc PyTypeObject.tp_iternext
An optional pointer to a function that returns the next item in an iterator.
- When the iterator is exhausted, it must return *NULL*; a :exc:`StopIteration`
+ When the iterator is exhausted, it must return ``NULL``; a :exc:`StopIteration`
exception may or may not be set. When another error occurs, it must return
- *NULL* too. Its presence signals that the instances of this type are
+ ``NULL`` too. Its presence signals that the instances of this type are
iterators.
Iterator types should also define the :c:member:`~PyTypeObject.tp_iter` function, and that
@@ -701,7 +713,7 @@ type objects) *must* have the :attr:`ob_size` field.
.. c:member:: struct PyMethodDef* PyTypeObject.tp_methods
- An optional pointer to a static *NULL*-terminated array of :c:type:`PyMethodDef`
+ An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMethodDef`
structures, declaring regular methods of this type.
For each entry in the array, an entry is added to the type's dictionary (see
@@ -713,7 +725,7 @@ type objects) *must* have the :attr:`ob_size` field.
.. c:member:: struct PyMemberDef* PyTypeObject.tp_members
- An optional pointer to a static *NULL*-terminated array of :c:type:`PyMemberDef`
+ An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMemberDef`
structures, declaring regular data members (fields or slots) of instances of
this type.
@@ -726,7 +738,7 @@ type objects) *must* have the :attr:`ob_size` field.
.. c:member:: struct PyGetSetDef* PyTypeObject.tp_getset
- An optional pointer to a static *NULL*-terminated array of :c:type:`PyGetSetDef`
+ An optional pointer to a static ``NULL``-terminated array of :c:type:`PyGetSetDef`
structures, declaring computed attributes of instances of this type.
For each entry in the array, an entry is added to the type's dictionary (see
@@ -751,7 +763,7 @@ type objects) *must* have the :attr:`ob_size` field.
The type's dictionary is stored here by :c:func:`PyType_Ready`.
- This field should normally be initialized to *NULL* before PyType_Ready is
+ This field should normally be initialized to ``NULL`` before PyType_Ready is
called; it may also be initialized to a dictionary containing initial attributes
for the type. Once :c:func:`PyType_Ready` has initialized the type, extra
attributes for the type may be added to this dictionary only if they don't
@@ -788,7 +800,7 @@ type objects) *must* have the :attr:`ob_size` field.
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
- The *value* argument is set to *NULL* to delete the value.
+ The *value* argument is set to ``NULL`` to delete the value.
This field is inherited by subtypes.
.. XXX explain.
@@ -864,7 +876,7 @@ type objects) *must* have the :attr:`ob_size` field.
arguments represent positional and keyword arguments of the call to
:meth:`__init__`.
- The :c:member:`~PyTypeObject.tp_init` function, if not *NULL*, is called when an instance is
+ The :c:member:`~PyTypeObject.tp_init` function, if not ``NULL``, is called when an instance is
created normally by calling its type, after the type's :c:member:`~PyTypeObject.tp_new` function
has returned an instance of the type. If the :c:member:`~PyTypeObject.tp_new` function returns an
instance of some other type that is not a subtype of the original type, no
@@ -905,7 +917,7 @@ type objects) *must* have the :attr:`ob_size` field.
An optional pointer to an instance creation function.
- If this function is *NULL* for a particular type, that type cannot be called to
+ If this function is ``NULL`` for a particular type, that type cannot be called to
create new instances; presumably there is some other way to create instances,
like a factory function.
@@ -928,7 +940,7 @@ type objects) *must* have the :attr:`ob_size` field.
deferred to :c:member:`~PyTypeObject.tp_init`.
This field is inherited by subtypes, except it is not inherited by static types
- whose :c:member:`~PyTypeObject.tp_base` is *NULL* or ``&PyBaseObject_Type``.
+ whose :c:member:`~PyTypeObject.tp_base` is ``NULL`` or ``&PyBaseObject_Type``.
.. c:member:: destructor PyTypeObject.tp_free
@@ -971,7 +983,7 @@ type objects) *must* have the :attr:`ob_size` field.
Tuple of base types.
- This is set for types created by a class statement. It should be *NULL* for
+ This is set for types created by a class statement. It should be ``NULL`` for
statically defined types.
This field is not inherited.
@@ -1167,22 +1179,25 @@ Mapping Object Structures
.. c:member:: lenfunc PyMappingMethods.mp_length
- This function is used by :c:func:`PyMapping_Length` and
+ This function is used by :c:func:`PyMapping_Size` and
:c:func:`PyObject_Size`, and has the same signature. This slot may be set to
- *NULL* if the object has no defined length.
+ ``NULL`` if the object has no defined length.
.. c:member:: binaryfunc PyMappingMethods.mp_subscript
- This function is used by :c:func:`PyObject_GetItem` and has the same
- signature. This slot must be filled for the :c:func:`PyMapping_Check`
- function to return ``1``, it can be *NULL* otherwise.
+ This function is used by :c:func:`PyObject_GetItem` and
+ :c:func:`PySequence_GetSlice`, and has the same signature as
+ :c:func:`!PyObject_GetItem`. This slot must be filled for the
+ :c:func:`PyMapping_Check` function to return ``1``, it can be ``NULL``
+ otherwise.
.. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
- This function is used by :c:func:`PyObject_SetItem` and
- :c:func:`PyObject_DelItem`. It has the same signature as
- :c:func:`PyObject_SetItem`, but *v* can also be set to *NULL* to delete
- an item. If this slot is *NULL*, the object does not support item
+ This function is used by :c:func:`PyObject_SetItem`,
+ :c:func:`PyObject_DelItem`, :c:func:`PyObject_SetSlice` and
+ :c:func:`PyObject_DelSlice`. It has the same signature as
+ :c:func:`!PyObject_SetItem`, but *v* can also be set to ``NULL`` to delete
+ an item. If this slot is ``NULL``, the object does not support item
assignment and deletion.
@@ -1201,58 +1216,69 @@ Sequence Object Structures
.. c:member:: lenfunc PySequenceMethods.sq_length
- This function is used by :c:func:`PySequence_Size` and :c:func:`PyObject_Size`,
- and has the same signature.
+ This function is used by :c:func:`PySequence_Size` and
+ :c:func:`PyObject_Size`, and has the same signature. It is also used for
+ handling negative indices via the :c:member:`~PySequenceMethods.sq_item`
+ and the :c:member:`~PySequenceMethods.sq_ass_item` slots.
.. c:member:: binaryfunc PySequenceMethods.sq_concat
This function is used by :c:func:`PySequence_Concat` and has the same
signature. It is also used by the ``+`` operator, after trying the numeric
- addition via the :c:member:`~PyTypeObject.tp_as_number.nb_add` slot.
+ addition via the :c:member:`~PyNumberMethods.nb_add` slot.
.. c:member:: ssizeargfunc PySequenceMethods.sq_repeat
This function is used by :c:func:`PySequence_Repeat` and has the same
signature. It is also used by the ``*`` operator, after trying numeric
- multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_multiply`
- slot.
+ multiplication via the :c:member:`~PyNumberMethods.nb_multiply` slot.
.. c:member:: ssizeargfunc PySequenceMethods.sq_item
This function is used by :c:func:`PySequence_GetItem` and has the same
- signature. This slot must be filled for the :c:func:`PySequence_Check`
- function to return ``1``, it can be *NULL* otherwise.
+ signature. It is also used by :c:func:`PyObject_GetItem`, after trying
+ the subscription via the :c:member:`~PyMappingMethods.mp_subscript` slot.
+ This slot must be filled for the :c:func:`PySequence_Check`
+ function to return ``1``, it can be ``NULL`` otherwise.
Negative indexes are handled as follows: if the :attr:`sq_length` slot is
filled, it is called and the sequence length is used to compute a positive
- index which is passed to :attr:`sq_item`. If :attr:`sq_length` is *NULL*,
+ index which is passed to :attr:`sq_item`. If :attr:`sq_length` is ``NULL``,
the index is passed as is to the function.
.. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item
This function is used by :c:func:`PySequence_SetItem` and has the same
- signature. This slot may be left to *NULL* if the object does not support
+ signature. It is also used by :c:func:`PyObject_SetItem` and
+ :c:func:`PyObject_DelItem`, after trying the item assignment and deletion
+ via the :c:member:`~PyMappingMethods.mp_ass_subscript` slot.
+ This slot may be left to ``NULL`` if the object does not support
item assignment and deletion.
.. c:member:: objobjproc PySequenceMethods.sq_contains
This function may be used by :c:func:`PySequence_Contains` and has the same
- signature. This slot may be left to *NULL*, in this case
- :c:func:`PySequence_Contains` simply traverses the sequence until it finds a
- match.
+ signature. This slot may be left to ``NULL``, in this case
+ :c:func:`!PySequence_Contains` simply traverses the sequence until it
+ finds a match.
.. c:member:: binaryfunc PySequenceMethods.sq_inplace_concat
This function is used by :c:func:`PySequence_InPlaceConcat` and has the same
- signature. It should modify its first operand, and return it.
+ signature. It should modify its first operand, and return it. This slot
+ may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceConcat`
+ will fall back to :c:func:`PySequence_Concat`. It is also used by the
+ augmented assignment ``+=``, after trying numeric in-place addition
+ via the :c:member:`~PyNumberMethods.nb_inplace_add` slot.
.. c:member:: ssizeargfunc PySequenceMethods.sq_inplace_repeat
This function is used by :c:func:`PySequence_InPlaceRepeat` and has the same
- signature. It should modify its first operand, and return it.
-
-.. XXX need to explain precedence between mapping and sequence
-.. XXX explains when to implement the sq_inplace_* slots
+ signature. It should modify its first operand, and return it. This slot
+ may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceRepeat`
+ will fall back to :c:func:`PySequence_Repeat`. It is also used by the
+ augmented assignment ``*=``, after trying numeric in-place multiplication
+ via the :c:member:`~PyNumberMethods.nb_inplace_multiply` slot.
.. _buffer-structs:
@@ -1281,7 +1307,7 @@ Buffer Object Structures
steps:
(1) Check if the request can be met. If not, raise :c:data:`PyExc_BufferError`,
- set :c:data:`view->obj` to *NULL* and return ``-1``.
+ set :c:data:`view->obj` to ``NULL`` and return ``-1``.
(2) Fill in the requested fields.
@@ -1327,7 +1353,7 @@ Buffer Object Structures
Handle a request to release the resources of the buffer. If no resources
need to be released, :c:member:`PyBufferProcs.bf_releasebuffer` may be
- *NULL*. Otherwise, a standard implementation of this function will take
+ ``NULL``. Otherwise, a standard implementation of this function will take
these optional steps:
(1) Decrement an internal counter for the number of exports.
@@ -1381,7 +1407,7 @@ Async Object Structures
The returned object must be an iterator, i.e. :c:func:`PyIter_Check` must
return ``1`` for it.
- This slot may be set to *NULL* if an object is not an :term:`awaitable`.
+ This slot may be set to ``NULL`` if an object is not an :term:`awaitable`.
.. c:member:: unaryfunc PyAsyncMethods.am_aiter
@@ -1391,7 +1417,7 @@ Async Object Structures
Must return an :term:`awaitable` object. See :meth:`__anext__` for details.
- This slot may be set to *NULL* if an object does not implement
+ This slot may be set to ``NULL`` if an object does not implement
asynchronous iteration protocol.
.. c:member:: unaryfunc PyAsyncMethods.am_anext
@@ -1401,4 +1427,4 @@ Async Object Structures
PyObject *am_anext(PyObject *self)
Must return an :term:`awaitable` object. See :meth:`__anext__` for details.
- This slot may be set to *NULL*.
+ This slot may be set to ``NULL``.
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 92e22b16a4ef29..35f67533badb12 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -22,14 +22,14 @@ in the Unicode object. The :c:type:`Py_UNICODE*` representation is deprecated
and inefficient; it should be avoided in performance- or memory-sensitive
situations.
-Due to the transition between the old APIs and the new APIs, unicode objects
+Due to the transition between the old APIs and the new APIs, Unicode objects
can internally be in two states depending on how they were created:
-* "canonical" unicode objects are all objects created by a non-deprecated
- unicode API. They use the most efficient representation allowed by the
+* "canonical" Unicode objects are all objects created by a non-deprecated
+ Unicode API. They use the most efficient representation allowed by the
implementation.
-* "legacy" unicode objects have been created through one of the deprecated
+* "legacy" Unicode objects have been created through one of the deprecated
APIs (typically :c:func:`PyUnicode_FromUnicode`) and only bear the
:c:type:`Py_UNICODE*` representation; you will have to call
:c:func:`PyUnicode_READY` on them before calling any other API.
@@ -152,7 +152,7 @@ access internal read-only data of Unicode objects:
.. c:function:: void* PyUnicode_DATA(PyObject *o)
- Return a void pointer to the raw unicode buffer. *o* has to be a Unicode
+ Return a void pointer to the raw Unicode buffer. *o* has to be a Unicode
object in the "canonical" representation (not checked).
.. versionadded:: 3.3
@@ -236,7 +236,7 @@ access internal read-only data of Unicode objects:
.. versionchanged:: 3.3
This macro is now inefficient -- because in many cases the
:c:type:`Py_UNICODE` representation does not exist and needs to be created
- -- and can fail (return *NULL* with an exception set). Try to port the
+ -- and can fail (return ``NULL`` with an exception set). Try to port the
code to use the new :c:func:`PyUnicode_nBYTE_DATA` macros or use
:c:func:`PyUnicode_WRITE` or :c:func:`PyUnicode_READ`.
@@ -413,11 +413,11 @@ APIs:
Create a Unicode object from the char buffer *u*. The bytes will be
interpreted as being UTF-8 encoded. The buffer is copied into the new
- object. If the buffer is not *NULL*, the return value might be a shared
+ object. If the buffer is not ``NULL``, the return value might be a shared
object, i.e. modification of the data is not allowed.
- If *u* is *NULL*, this function behaves like :c:func:`PyUnicode_FromUnicode`
- with the buffer set to *NULL*. This usage is deprecated in favor of
+ If *u* is ``NULL``, this function behaves like :c:func:`PyUnicode_FromUnicode`
+ with the buffer set to ``NULL``. This usage is deprecated in favor of
:c:func:`PyUnicode_New`.
@@ -430,7 +430,7 @@ APIs:
.. c:function:: PyObject* PyUnicode_FromFormat(const char *format, ...)
Take a C :c:func:`printf`\ -style *format* string and a variable number of
- arguments, calculate the size of the resulting Python unicode string and return
+ arguments, calculate the size of the resulting Python Unicode string and return
a string with the values formatted into it. The variable arguments must be C
types and must correspond exactly to the format characters in the *format*
ASCII-encoded string. The following format characters are allowed:
@@ -443,82 +443,82 @@ APIs:
.. tabularcolumns:: |l|l|L|
- +-------------------+---------------------+--------------------------------+
- | Format Characters | Type | Comment |
- +===================+=====================+================================+
- | :attr:`%%` | *n/a* | The literal % character. |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%c` | int | A single character, |
- | | | represented as a C int. |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%d` | int | Equivalent to |
- | | | ``printf("%d")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%u` | unsigned int | Equivalent to |
- | | | ``printf("%u")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%ld` | long | Equivalent to |
- | | | ``printf("%ld")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%li` | long | Equivalent to |
- | | | ``printf("%li")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%lu` | unsigned long | Equivalent to |
- | | | ``printf("%lu")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%lld` | long long | Equivalent to |
- | | | ``printf("%lld")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%lli` | long long | Equivalent to |
- | | | ``printf("%lli")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%llu` | unsigned long long | Equivalent to |
- | | | ``printf("%llu")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%zd` | Py_ssize_t | Equivalent to |
- | | | ``printf("%zd")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%zi` | Py_ssize_t | Equivalent to |
- | | | ``printf("%zi")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%zu` | size_t | Equivalent to |
- | | | ``printf("%zu")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%i` | int | Equivalent to |
- | | | ``printf("%i")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%x` | int | Equivalent to |
- | | | ``printf("%x")``. [1]_ |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%s` | const char\* | A null-terminated C character |
- | | | array. |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%p` | const void\* | The hex representation of a C |
- | | | pointer. Mostly equivalent to |
- | | | ``printf("%p")`` except that |
- | | | it is guaranteed to start with |
- | | | the literal ``0x`` regardless |
- | | | of what the platform's |
- | | | ``printf`` yields. |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%A` | PyObject\* | The result of calling |
- | | | :func:`ascii`. |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%U` | PyObject\* | A unicode object. |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%V` | PyObject\*, | A unicode object (which may be |
- | | const char\* | *NULL*) and a null-terminated |
- | | | C character array as a second |
- | | | parameter (which will be used, |
- | | | if the first parameter is |
- | | | *NULL*). |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%S` | PyObject\* | The result of calling |
- | | | :c:func:`PyObject_Str`. |
- +-------------------+---------------------+--------------------------------+
- | :attr:`%R` | PyObject\* | The result of calling |
- | | | :c:func:`PyObject_Repr`. |
- +-------------------+---------------------+--------------------------------+
+ +-------------------+---------------------+----------------------------------+
+ | Format Characters | Type | Comment |
+ +===================+=====================+==================================+
+ | :attr:`%%` | *n/a* | The literal % character. |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%c` | int | A single character, |
+ | | | represented as a C int. |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%d` | int | Equivalent to |
+ | | | ``printf("%d")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%u` | unsigned int | Equivalent to |
+ | | | ``printf("%u")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%ld` | long | Equivalent to |
+ | | | ``printf("%ld")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%li` | long | Equivalent to |
+ | | | ``printf("%li")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%lu` | unsigned long | Equivalent to |
+ | | | ``printf("%lu")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%lld` | long long | Equivalent to |
+ | | | ``printf("%lld")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%lli` | long long | Equivalent to |
+ | | | ``printf("%lli")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%llu` | unsigned long long | Equivalent to |
+ | | | ``printf("%llu")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%zd` | Py_ssize_t | Equivalent to |
+ | | | ``printf("%zd")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%zi` | Py_ssize_t | Equivalent to |
+ | | | ``printf("%zi")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%zu` | size_t | Equivalent to |
+ | | | ``printf("%zu")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%i` | int | Equivalent to |
+ | | | ``printf("%i")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%x` | int | Equivalent to |
+ | | | ``printf("%x")``. [1]_ |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%s` | const char\* | A null-terminated C character |
+ | | | array. |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%p` | const void\* | The hex representation of a C |
+ | | | pointer. Mostly equivalent to |
+ | | | ``printf("%p")`` except that |
+ | | | it is guaranteed to start with |
+ | | | the literal ``0x`` regardless |
+ | | | of what the platform's |
+ | | | ``printf`` yields. |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%A` | PyObject\* | The result of calling |
+ | | | :func:`ascii`. |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%U` | PyObject\* | A Unicode object. |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%V` | PyObject\*, | A Unicode object (which may be |
+ | | const char\* | ``NULL``) and a null-terminated |
+ | | | C character array as a second |
+ | | | parameter (which will be used, |
+ | | | if the first parameter is |
+ | | | ``NULL``). |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%S` | PyObject\* | The result of calling |
+ | | | :c:func:`PyObject_Str`. |
+ +-------------------+---------------------+----------------------------------+
+ | :attr:`%R` | PyObject\* | The result of calling |
+ | | | :c:func:`PyObject_Repr`. |
+ +-------------------+---------------------+----------------------------------+
An unrecognized format character causes all the rest of the format string to be
copied as-is to the result string, and any extra arguments discarded.
@@ -526,9 +526,9 @@ APIs:
.. note::
The width formatter unit is number of characters rather than bytes.
The precision formatter unit is number of bytes for ``"%s"`` and
- ``"%V"`` (if the ``PyObject*`` argument is NULL), and a number of
+ ``"%V"`` (if the ``PyObject*`` argument is ``NULL``), and a number of
characters for ``"%A"``, ``"%U"``, ``"%S"``, ``"%R"`` and ``"%V"``
- (if the ``PyObject*`` argument is not NULL).
+ (if the ``PyObject*`` argument is not ``NULL``).
.. [1] For integer specifiers (d, u, ld, li, lu, lld, lli, llu, zd, zi,
zu, i, x): the 0-conversion flag has effect even when a precision is given.
@@ -558,13 +558,13 @@ APIs:
:class:`bytes`, :class:`bytearray` and other
:term:`bytes-like objects `
are decoded according to the given *encoding* and using the error handling
- defined by *errors*. Both can be *NULL* to have the interface use the default
+ defined by *errors*. Both can be ``NULL`` to have the interface use the default
values (see :ref:`builtincodecs` for details).
All other objects, including Unicode objects, cause a :exc:`TypeError` to be
set.
- The API returns *NULL* if there was an error. The caller is responsible for
+ The API returns ``NULL`` if there was an error. The caller is responsible for
decref'ing the returned objects.
@@ -640,7 +640,7 @@ APIs:
Py_ssize_t buflen, int copy_null)
Copy the string *u* into a UCS4 buffer, including a null character, if
- *copy_null* is set. Returns *NULL* and sets an exception on error (in
+ *copy_null* is set. Returns ``NULL`` and sets an exception on error (in
particular, a :exc:`SystemError` if *buflen* is smaller than the length of
*u*). *buffer* is returned on success.
@@ -650,7 +650,7 @@ APIs:
.. c:function:: Py_UCS4* PyUnicode_AsUCS4Copy(PyObject *u)
Copy the string *u* into a new UCS4 buffer that is allocated using
- :c:func:`PyMem_Malloc`. If this fails, *NULL* is returned with a
+ :c:func:`PyMem_Malloc`. If this fails, ``NULL`` is returned with a
:exc:`MemoryError` set. The returned buffer always has an extra
null code point appended.
@@ -670,15 +670,15 @@ Extension modules can continue using them, as they will not be removed in Python
.. c:function:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size)
Create a Unicode object from the Py_UNICODE buffer *u* of the given size. *u*
- may be *NULL* which causes the contents to be undefined. It is the user's
+ may be ``NULL`` which causes the contents to be undefined. It is the user's
responsibility to fill in the needed data. The buffer is copied into the new
object.
- If the buffer is not *NULL*, the return value might be a shared object.
+ If the buffer is not ``NULL``, the return value might be a shared object.
Therefore, modification of the resulting Unicode object is only allowed when
- *u* is *NULL*.
+ *u* is ``NULL``.
- If the buffer is *NULL*, :c:func:`PyUnicode_READY` must be called once the
+ If the buffer is ``NULL``, :c:func:`PyUnicode_READY` must be called once the
string content has been filled before using any of the access macros such as
:c:func:`PyUnicode_KIND`.
@@ -689,7 +689,7 @@ Extension modules can continue using them, as they will not be removed in Python
.. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode)
Return a read-only pointer to the Unicode object's internal
- :c:type:`Py_UNICODE` buffer, or *NULL* on error. This will create the
+ :c:type:`Py_UNICODE` buffer, or ``NULL`` on error. This will create the
:c:type:`Py_UNICODE*` representation of the object if it is not yet
available. The buffer is always terminated with an extra null code point.
Note that the resulting :c:type:`Py_UNICODE` string may also contain
@@ -705,7 +705,7 @@ Extension modules can continue using them, as they will not be removed in Python
Create a Unicode object by replacing all decimal digits in
:c:type:`Py_UNICODE` buffer of the given *size* by ASCII digits 0--9
- according to their decimal value. Return *NULL* if an exception occurs.
+ according to their decimal value. Return ``NULL`` if an exception occurs.
.. c:function:: Py_UNICODE* PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size)
@@ -721,7 +721,7 @@ Extension modules can continue using them, as they will not be removed in Python
.. c:function:: Py_UNICODE* PyUnicode_AsUnicodeCopy(PyObject *unicode)
- Create a copy of a Unicode string ending with a null code point. Return *NULL*
+ Create a copy of a Unicode string ending with a null code point. Return ``NULL``
and raise a :exc:`MemoryError` exception on memory allocation failure,
otherwise return a new allocated buffer (use :c:func:`PyMem_Free` to free
the buffer). Note that the resulting :c:type:`Py_UNICODE*` string may
@@ -932,10 +932,10 @@ wchar_t Support
Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*.
Passing ``-1`` as the *size* indicates that the function must itself compute the length,
using wcslen.
- Return *NULL* on failure.
+ Return ``NULL`` on failure.
-.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size)
+.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size)
Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most
*size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing
@@ -951,22 +951,22 @@ wchar_t Support
.. c:function:: wchar_t* PyUnicode_AsWideCharString(PyObject *unicode, Py_ssize_t *size)
Convert the Unicode object to a wide character string. The output string
- always ends with a null character. If *size* is not *NULL*, write the number
+ always ends with a null character. If *size* is not ``NULL``, write the number
of wide characters (excluding the trailing null termination character) into
*\*size*. Note that the resulting :c:type:`wchar_t` string might contain
null characters, which would cause the string to be truncated when used with
- most C functions. If *size* is *NULL* and the :c:type:`wchar_t*` string
+ most C functions. If *size* is ``NULL`` and the :c:type:`wchar_t*` string
contains null characters a :exc:`ValueError` is raised.
Returns a buffer allocated by :c:func:`PyMem_Alloc` (use
- :c:func:`PyMem_Free` to free it) on success. On error, returns *NULL*
+ :c:func:`PyMem_Free` to free it) on success. On error, returns ``NULL``
and *\*size* is undefined. Raises a :exc:`MemoryError` if memory allocation
is failed.
.. versionadded:: 3.2
.. versionchanged:: 3.7
- Raises a :exc:`ValueError` if *size* is *NULL* and the :c:type:`wchar_t*`
+ Raises a :exc:`ValueError` if *size* is ``NULL`` and the :c:type:`wchar_t*`
string contains null characters.
@@ -982,7 +982,7 @@ Many of the following APIs take two arguments encoding and errors, and they
have the same semantics as the ones of the built-in :func:`str` string object
constructor.
-Setting encoding to *NULL* causes the default encoding to be used
+Setting encoding to ``NULL`` causes the default encoding to be used
which is ASCII. The file system calls should use
:c:func:`PyUnicode_FSConverter` for encoding file names. This uses the
variable :c:data:`Py_FileSystemDefaultEncoding` internally. This
@@ -990,7 +990,7 @@ variable should be treated as read-only: on some systems, it will be a
pointer to a static string, on others, it will change at run-time
(such as when the application invokes setlocale).
-Error handling is set by errors which may also be set to *NULL* meaning to use
+Error handling is set by errors which may also be set to ``NULL`` meaning to use
the default handling defined for the codec. Default error handling for all
built-in codecs is "strict" (:exc:`ValueError` is raised).
@@ -1010,7 +1010,7 @@ These are the generic codec APIs:
Create a Unicode object by decoding *size* bytes of the encoded string *s*.
*encoding* and *errors* have the same meaning as the parameters of the same name
in the :func:`str` built-in function. The codec to be used is looked up
- using the Python codec registry. Return *NULL* if an exception was raised by
+ using the Python codec registry. Return ``NULL`` if an exception was raised by
the codec.
@@ -1020,7 +1020,7 @@ These are the generic codec APIs:
Encode a Unicode object and return the result as Python bytes object.
*encoding* and *errors* have the same meaning as the parameters of the same
name in the Unicode :meth:`~str.encode` method. The codec to be used is looked up
- using the Python codec registry. Return *NULL* if an exception was raised by
+ using the Python codec registry. Return ``NULL`` if an exception was raised by
the codec.
@@ -1030,7 +1030,7 @@ These are the generic codec APIs:
Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* and return a Python
bytes object. *encoding* and *errors* have the same meaning as the
parameters of the same name in the Unicode :meth:`~str.encode` method. The codec
- to be used is looked up using the Python codec registry. Return *NULL* if an
+ to be used is looked up using the Python codec registry. Return ``NULL`` if an
exception was raised by the codec.
.. deprecated-removed:: 3.3 4.0
@@ -1047,14 +1047,14 @@ These are the UTF-8 codec APIs:
.. c:function:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string
- *s*. Return *NULL* if an exception was raised by the codec.
+ *s*. Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, \
const char *errors, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF8`. If
- *consumed* is not *NULL*, trailing incomplete UTF-8 byte sequences will not be
+ If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF8`. If
+ *consumed* is not ``NULL``, trailing incomplete UTF-8 byte sequences will not be
treated as an error. Those bytes will not be decoded and the number of bytes
that have been decoded will be stored in *consumed*.
@@ -1062,7 +1062,7 @@ These are the UTF-8 codec APIs:
.. c:function:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode)
Encode a Unicode object using UTF-8 and return the result as Python bytes
- object. Error handling is "strict". Return *NULL* if an exception was
+ object. Error handling is "strict". Return ``NULL`` if an exception was
raised by the codec.
@@ -1070,11 +1070,11 @@ These are the UTF-8 codec APIs:
Return a pointer to the UTF-8 encoding of the Unicode object, and
store the size of the encoded representation (in bytes) in *size*. The
- *size* argument can be *NULL*; in this case no size will be stored. The
+ *size* argument can be ``NULL``; in this case no size will be stored. The
returned buffer always has an extra null byte appended (not included in
*size*), regardless of whether there are any other null code points.
- In the case of an error, *NULL* is returned with an exception set and no
+ In the case of an error, ``NULL`` is returned with an exception set and no
*size* is stored.
This caches the UTF-8 representation of the string in the Unicode object, and
@@ -1100,7 +1100,7 @@ These are the UTF-8 codec APIs:
.. c:function:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
Encode the :c:type:`Py_UNICODE` buffer *s* of the given *size* using UTF-8 and
- return a Python bytes object. Return *NULL* if an exception was raised by
+ return a Python bytes object. Return ``NULL`` if an exception was raised by
the codec.
.. deprecated-removed:: 3.3 4.0
@@ -1119,10 +1119,10 @@ These are the UTF-32 codec APIs:
const char *errors, int *byteorder)
Decode *size* bytes from a UTF-32 encoded buffer string and return the
- corresponding Unicode object. *errors* (if non-*NULL*) defines the error
+ corresponding Unicode object. *errors* (if non-``NULL``) defines the error
handling. It defaults to "strict".
- If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte
+ If *byteorder* is non-``NULL``, the decoder starts decoding using the given byte
order::
*byteorder == -1: little endian
@@ -1137,16 +1137,16 @@ These are the UTF-32 codec APIs:
After completion, *\*byteorder* is set to the current byte order at the end
of input data.
- If *byteorder* is *NULL*, the codec starts in native order mode.
+ If *byteorder* is ``NULL``, the codec starts in native order mode.
- Return *NULL* if an exception was raised by the codec.
+ Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, \
const char *errors, int *byteorder, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF32`. If
- *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeUTF32Stateful` will not treat
+ If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF32`. If
+ *consumed* is not ``NULL``, :c:func:`PyUnicode_DecodeUTF32Stateful` will not treat
trailing incomplete UTF-32 byte sequences (such as a number of bytes not divisible
by four) as an error. Those bytes will not be decoded and the number of bytes
that have been decoded will be stored in *consumed*.
@@ -1156,7 +1156,7 @@ These are the UTF-32 codec APIs:
Return a Python byte string using the UTF-32 encoding in native byte
order. The string always starts with a BOM mark. Error handling is "strict".
- Return *NULL* if an exception was raised by the codec.
+ Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, \
@@ -1172,10 +1172,10 @@ These are the UTF-32 codec APIs:
If byteorder is ``0``, the output string will always start with the Unicode BOM
mark (U+FEFF). In the other two modes, no BOM mark is prepended.
- If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output
+ If ``Py_UNICODE_WIDE`` is not defined, surrogate pairs will be output
as a single code point.
- Return *NULL* if an exception was raised by the codec.
+ Return ``NULL`` if an exception was raised by the codec.
.. deprecated-removed:: 3.3 4.0
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
@@ -1192,10 +1192,10 @@ These are the UTF-16 codec APIs:
const char *errors, int *byteorder)
Decode *size* bytes from a UTF-16 encoded buffer string and return the
- corresponding Unicode object. *errors* (if non-*NULL*) defines the error
+ corresponding Unicode object. *errors* (if non-``NULL``) defines the error
handling. It defaults to "strict".
- If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte
+ If *byteorder* is non-``NULL``, the decoder starts decoding using the given byte
order::
*byteorder == -1: little endian
@@ -1211,16 +1211,16 @@ These are the UTF-16 codec APIs:
After completion, *\*byteorder* is set to the current byte order at the end
of input data.
- If *byteorder* is *NULL*, the codec starts in native order mode.
+ If *byteorder* is ``NULL``, the codec starts in native order mode.
- Return *NULL* if an exception was raised by the codec.
+ Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, \
const char *errors, int *byteorder, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF16`. If
- *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeUTF16Stateful` will not treat
+ If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF16`. If
+ *consumed* is not ``NULL``, :c:func:`PyUnicode_DecodeUTF16Stateful` will not treat
trailing incomplete UTF-16 byte sequences (such as an odd number of bytes or a
split surrogate pair) as an error. Those bytes will not be decoded and the
number of bytes that have been decoded will be stored in *consumed*.
@@ -1230,7 +1230,7 @@ These are the UTF-16 codec APIs:
Return a Python byte string using the UTF-16 encoding in native byte
order. The string always starts with a BOM mark. Error handling is "strict".
- Return *NULL* if an exception was raised by the codec.
+ Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, \
@@ -1246,11 +1246,11 @@ These are the UTF-16 codec APIs:
If byteorder is ``0``, the output string will always start with the Unicode BOM
mark (U+FEFF). In the other two modes, no BOM mark is prepended.
- If *Py_UNICODE_WIDE* is defined, a single :c:type:`Py_UNICODE` value may get
+ If ``Py_UNICODE_WIDE`` is defined, a single :c:type:`Py_UNICODE` value may get
represented as a surrogate pair. If it is not defined, each :c:type:`Py_UNICODE`
values is interpreted as a UCS-2 character.
- Return *NULL* if an exception was raised by the codec.
+ Return ``NULL`` if an exception was raised by the codec.
.. deprecated-removed:: 3.3 4.0
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
@@ -1266,14 +1266,14 @@ These are the UTF-7 codec APIs:
.. c:function:: PyObject* PyUnicode_DecodeUTF7(const char *s, Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the UTF-7 encoded string
- *s*. Return *NULL* if an exception was raised by the codec.
+ *s*. Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_DecodeUTF7Stateful(const char *s, Py_ssize_t size, \
const char *errors, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeUTF7`. If
- *consumed* is not *NULL*, trailing incomplete UTF-7 base-64 sections will not
+ If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF7`. If
+ *consumed* is not ``NULL``, trailing incomplete UTF-7 base-64 sections will not
be treated as an error. Those bytes will not be decoded and the number of
bytes that have been decoded will be stored in *consumed*.
@@ -1282,7 +1282,7 @@ These are the UTF-7 codec APIs:
int base64SetO, int base64WhiteSpace, const char *errors)
Encode the :c:type:`Py_UNICODE` buffer of the given size using UTF-7 and
- return a Python bytes object. Return *NULL* if an exception was raised by
+ return a Python bytes object. Return ``NULL`` if an exception was raised by
the codec.
If *base64SetO* is nonzero, "Set O" (punctuation that has no otherwise
@@ -1305,20 +1305,20 @@ These are the "Unicode Escape" codec APIs:
Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded
- string *s*. Return *NULL* if an exception was raised by the codec.
+ string *s*. Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
Encode a Unicode object using Unicode-Escape and return the result as a
- bytes object. Error handling is "strict". Return *NULL* if an exception was
+ bytes object. Error handling is "strict". Return ``NULL`` if an exception was
raised by the codec.
.. c:function:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size)
Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Unicode-Escape and
- return a bytes object. Return *NULL* if an exception was raised by the codec.
+ return a bytes object. Return ``NULL`` if an exception was raised by the codec.
.. deprecated-removed:: 3.3 4.0
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
@@ -1335,21 +1335,21 @@ These are the "Raw Unicode Escape" codec APIs:
Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape
- encoded string *s*. Return *NULL* if an exception was raised by the codec.
+ encoded string *s*. Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
Encode a Unicode object using Raw-Unicode-Escape and return the result as
- a bytes object. Error handling is "strict". Return *NULL* if an exception
+ a bytes object. Error handling is "strict". Return ``NULL`` if an exception
was raised by the codec.
.. c:function:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, \
- Py_ssize_t size, const char *errors)
+ Py_ssize_t size)
Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Raw-Unicode-Escape
- and return a bytes object. Return *NULL* if an exception was raised by the codec.
+ and return a bytes object. Return ``NULL`` if an exception was raised by the codec.
.. deprecated-removed:: 3.3 4.0
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
@@ -1367,20 +1367,20 @@ ordinals and only these are accepted by the codecs during encoding.
.. c:function:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string
- *s*. Return *NULL* if an exception was raised by the codec.
+ *s*. Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode)
Encode a Unicode object using Latin-1 and return the result as Python bytes
- object. Error handling is "strict". Return *NULL* if an exception was
+ object. Error handling is "strict". Return ``NULL`` if an exception was
raised by the codec.
.. c:function:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
Encode the :c:type:`Py_UNICODE` buffer of the given *size* using Latin-1 and
- return a Python bytes object. Return *NULL* if an exception was raised by
+ return a Python bytes object. Return ``NULL`` if an exception was raised by
the codec.
.. deprecated-removed:: 3.3 4.0
@@ -1399,20 +1399,20 @@ codes generate errors.
.. c:function:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the ASCII encoded string
- *s*. Return *NULL* if an exception was raised by the codec.
+ *s*. Return ``NULL`` if an exception was raised by the codec.
.. c:function:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode)
Encode a Unicode object using ASCII and return the result as Python bytes
- object. Error handling is "strict". Return *NULL* if an exception was
+ object. Error handling is "strict". Return ``NULL`` if an exception was
raised by the codec.
.. c:function:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
Encode the :c:type:`Py_UNICODE` buffer of the given *size* using ASCII and
- return a Python bytes object. Return *NULL* if an exception was raised by
+ return a Python bytes object. Return ``NULL`` if an exception was raised by
the codec.
.. deprecated-removed:: 3.3 4.0
@@ -1436,10 +1436,10 @@ These are the mapping codec APIs:
PyObject *mapping, const char *errors)
Create a Unicode object by decoding *size* bytes of the encoded string *s*
- using the given *mapping* object. Return *NULL* if an exception was raised
+ using the given *mapping* object. Return ``NULL`` if an exception was raised
by the codec.
- If *mapping* is *NULL*, Latin-1 decoding will be applied. Else
+ If *mapping* is ``NULL``, Latin-1 decoding will be applied. Else
*mapping* must map bytes ordinals (integers in the range from 0 to 255)
to Unicode strings, integers (which are then interpreted as Unicode
ordinals) or ``None``. Unmapped data bytes -- ones which cause a
@@ -1451,7 +1451,7 @@ These are the mapping codec APIs:
.. c:function:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping)
Encode a Unicode object using the given *mapping* object and return the
- result as a bytes object. Error handling is "strict". Return *NULL* if an
+ result as a bytes object. Error handling is "strict". Return ``NULL`` if an
exception was raised by the codec.
The *mapping* object must map Unicode ordinal integers to bytes objects,
@@ -1464,7 +1464,7 @@ These are the mapping codec APIs:
PyObject *mapping, const char *errors)
Encode the :c:type:`Py_UNICODE` buffer of the given *size* using the given
- *mapping* object and return the result as a bytes object. Return *NULL* if
+ *mapping* object and return the result as a bytes object. Return ``NULL`` if
an exception was raised by the codec.
.. deprecated-removed:: 3.3 4.0
@@ -1479,7 +1479,7 @@ The following codec API is special in that maps Unicode to Unicode.
PyObject *mapping, const char *errors)
Translate a Unicode object using the given *mapping* object and return the
- resulting Unicode object. Return *NULL* if an exception was raised by the
+ resulting Unicode object. Return ``NULL`` if an exception was raised by the
codec.
The *mapping* object must map Unicode ordinal integers to Unicode strings,
@@ -1493,7 +1493,7 @@ The following codec API is special in that maps Unicode to Unicode.
Translate a :c:type:`Py_UNICODE` buffer of the given *size* by applying a
character *mapping* table to it and return the resulting Unicode object.
- Return *NULL* when an exception was raised by the codec.
+ Return ``NULL`` when an exception was raised by the codec.
.. deprecated-removed:: 3.3 4.0
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
@@ -1512,14 +1512,14 @@ the user settings on the machine running the codec.
.. c:function:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors)
Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*.
- Return *NULL* if an exception was raised by the codec.
+ Return ``NULL`` if an exception was raised by the codec.
-.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, \
- const char *errors, int *consumed)
+.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, Py_ssize_t size, \
+ const char *errors, Py_ssize_t *consumed)
- If *consumed* is *NULL*, behave like :c:func:`PyUnicode_DecodeMBCS`. If
- *consumed* is not *NULL*, :c:func:`PyUnicode_DecodeMBCSStateful` will not decode
+ If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeMBCS`. If
+ *consumed* is not ``NULL``, :c:func:`PyUnicode_DecodeMBCSStateful` will not decode
trailing lead byte and the number of bytes that have been decoded will be stored
in *consumed*.
@@ -1527,14 +1527,14 @@ the user settings on the machine running the codec.
.. c:function:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode)
Encode a Unicode object using MBCS and return the result as Python bytes
- object. Error handling is "strict". Return *NULL* if an exception was
+ object. Error handling is "strict". Return ``NULL`` if an exception was
raised by the codec.
.. c:function:: PyObject* PyUnicode_EncodeCodePage(int code_page, PyObject *unicode, const char *errors)
Encode the Unicode object using the specified code page and return a Python
- bytes object. Return *NULL* if an exception was raised by the codec. Use
+ bytes object. Return ``NULL`` if an exception was raised by the codec. Use
:c:data:`CP_ACP` code page to get the MBCS encoder.
.. versionadded:: 3.3
@@ -1543,7 +1543,7 @@ the user settings on the machine running the codec.
.. c:function:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors)
Encode the :c:type:`Py_UNICODE` buffer of the given *size* using MBCS and return
- a Python bytes object. Return *NULL* if an exception was raised by the
+ a Python bytes object. Return ``NULL`` if an exception was raised by the
codec.
.. deprecated-removed:: 3.3 4.0
@@ -1565,7 +1565,7 @@ The following APIs are capable of handling Unicode objects and strings on input
(we refer to them as strings in the descriptions) and return Unicode objects or
integers as appropriate.
-They all return *NULL* or ``-1`` if an exception occurs.
+They all return ``NULL`` or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_Concat(PyObject *left, PyObject *right)
@@ -1575,7 +1575,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit)
- Split a string giving a list of Unicode strings. If *sep* is *NULL*, splitting
+ Split a string giving a list of Unicode strings. If *sep* is ``NULL``, splitting
will be done at all whitespace substrings. Otherwise, splits occur at the given
separator. At most *maxsplit* splits will be done. If negative, no limit is
set. Separators are not included in the resulting list.
@@ -1601,7 +1601,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
and sequences work well. Unmapped character ordinals (ones which cause a
:exc:`LookupError`) are left untouched and are copied as-is.
- *errors* has the usual meaning for codecs. It may be *NULL* which indicates to
+ *errors* has the usual meaning for codecs. It may be ``NULL`` which indicates to
use the default error handling.
@@ -1670,7 +1670,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: int PyUnicode_CompareWithASCIIString(PyObject *uni, const char *string)
- Compare a unicode object, *uni*, with *string* and return ``-1``, ``0``, ``1`` for less
+ Compare a Unicode object, *uni*, with *string* and return ``-1``, ``0``, ``1`` for less
than, equal, and greater than, respectively. It is best to pass only
ASCII-encoded strings, but the function interprets the input string as
ISO-8859-1 if it contains non-ASCII characters.
@@ -1680,7 +1680,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
- Rich compare two unicode strings and return one of the following:
+ Rich compare two Unicode strings and return one of the following:
* ``NULL`` in case an exception was raised
* :const:`Py_True` or :const:`Py_False` for successful comparisons
@@ -1708,7 +1708,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: void PyUnicode_InternInPlace(PyObject **string)
Intern the argument *\*string* in place. The argument must be the address of a
- pointer variable pointing to a Python unicode string object. If there is an
+ pointer variable pointing to a Python Unicode string object. If there is an
existing interned string that is the same as *\*string*, it sets *\*string* to
it (decrementing the reference count of the old string object and incrementing
the reference count of the interned string object), otherwise it leaves
@@ -1721,6 +1721,6 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_InternFromString(const char *v)
A combination of :c:func:`PyUnicode_FromString` and
- :c:func:`PyUnicode_InternInPlace`, returning either a new unicode string
+ :c:func:`PyUnicode_InternInPlace`, returning either a new Unicode string
object that has been interned, or a new ("owned") reference to an earlier
interned string object with the same value.
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index cefe9d44bf45a2..49a7a0c591a2c9 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -45,7 +45,7 @@ the same library that the Python runtime is using.
.. c:function:: int PyRun_AnyFile(FILE *fp, const char *filename)
This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving
- *closeit* set to ``0`` and *flags* set to *NULL*.
+ *closeit* set to ``0`` and *flags* set to ``NULL``.
.. c:function:: int PyRun_AnyFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
@@ -57,7 +57,7 @@ the same library that the Python runtime is using.
.. c:function:: int PyRun_AnyFileEx(FILE *fp, const char *filename, int closeit)
This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving
- the *flags* argument set to *NULL*.
+ the *flags* argument set to ``NULL``.
.. c:function:: int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
@@ -66,14 +66,14 @@ the same library that the Python runtime is using.
terminal input or Unix pseudo-terminal), return the value of
:c:func:`PyRun_InteractiveLoop`, otherwise return the result of
:c:func:`PyRun_SimpleFile`. *filename* is decoded from the filesystem
- encoding (:func:`sys.getfilesystemencoding`). If *filename* is *NULL*, this
+ encoding (:func:`sys.getfilesystemencoding`). If *filename* is ``NULL``, this
function uses ``"???"`` as the filename.
.. c:function:: int PyRun_SimpleString(const char *command)
This is a simplified interface to :c:func:`PyRun_SimpleStringFlags` below,
- leaving the *PyCompilerFlags\** argument set to NULL.
+ leaving the :c:type:`PyCompilerFlags`\* argument set to ``NULL``.
.. c:function:: int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
@@ -92,13 +92,13 @@ the same library that the Python runtime is using.
.. c:function:: int PyRun_SimpleFile(FILE *fp, const char *filename)
This is a simplified interface to :c:func:`PyRun_SimpleFileExFlags` below,
- leaving *closeit* set to ``0`` and *flags* set to *NULL*.
+ leaving *closeit* set to ``0`` and *flags* set to ``NULL``.
.. c:function:: int PyRun_SimpleFileEx(FILE *fp, const char *filename, int closeit)
This is a simplified interface to :c:func:`PyRun_SimpleFileExFlags` below,
- leaving *flags* set to *NULL*.
+ leaving *flags* set to ``NULL``.
.. c:function:: int PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
@@ -109,11 +109,15 @@ the same library that the Python runtime is using.
(:func:`sys.getfilesystemencoding`). If *closeit* is true, the file is
closed before PyRun_SimpleFileExFlags returns.
+ .. note::
+ On Windows, *fp* should be opened as binary mode (e.g. ``fopen(filename, "rb")``.
+ Otherwise, Python may not handle script file with LF line ending correctly.
+
.. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename)
This is a simplified interface to :c:func:`PyRun_InteractiveOneFlags` below,
- leaving *flags* set to *NULL*.
+ leaving *flags* set to ``NULL``.
.. c:function:: int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
@@ -133,7 +137,7 @@ the same library that the Python runtime is using.
.. c:function:: int PyRun_InteractiveLoop(FILE *fp, const char *filename)
This is a simplified interface to :c:func:`PyRun_InteractiveLoopFlags` below,
- leaving *flags* set to *NULL*.
+ leaving *flags* set to ``NULL``.
.. c:function:: int PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
@@ -162,13 +166,13 @@ the same library that the Python runtime is using.
``char *func(FILE *stdin, FILE *stdout, char *prompt)``,
overriding the default function used to read a single line of input
at the interpreter's prompt. The function is expected to output
- the string *prompt* if it's not *NULL*, and then read a line of
+ the string *prompt* if it's not ``NULL``, and then read a line of
input from the provided standard input file, returning the
resulting string. For example, The :mod:`readline` module sets
this hook to provide line-editing and tab-completion features.
The result must be a string allocated by :c:func:`PyMem_RawMalloc` or
- :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred.
+ :c:func:`PyMem_RawRealloc`, or ``NULL`` if an error occurred.
.. versionchanged:: 3.4
The result must be allocated by :c:func:`PyMem_RawMalloc` or
@@ -180,14 +184,14 @@ the same library that the Python runtime is using.
This is a simplified interface to
:c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
- to *NULL* and *flags* set to ``0``.
+ to ``NULL`` and *flags* set to ``0``.
.. c:function:: struct _node* PyParser_SimpleParseStringFlags( const char *str, int start, int flags)
This is a simplified interface to
:c:func:`PyParser_SimpleParseStringFlagsFilename` below, leaving *filename* set
- to *NULL*.
+ to ``NULL``.
.. c:function:: struct _node* PyParser_SimpleParseStringFlagsFilename( const char *str, const char *filename, int start, int flags)
@@ -214,7 +218,7 @@ the same library that the Python runtime is using.
.. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
This is a simplified interface to :c:func:`PyRun_StringFlags` below, leaving
- *flags* set to *NULL*.
+ *flags* set to ``NULL``.
.. c:function:: PyObject* PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)
@@ -225,20 +229,20 @@ the same library that the Python runtime is using.
that implements the mapping protocol. The parameter *start* specifies
the start token that should be used to parse the source code.
- Returns the result of executing the code as a Python object, or *NULL* if an
+ Returns the result of executing the code as a Python object, or ``NULL`` if an
exception was raised.
.. c:function:: PyObject* PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals)
This is a simplified interface to :c:func:`PyRun_FileExFlags` below, leaving
- *closeit* set to ``0`` and *flags* set to *NULL*.
+ *closeit* set to ``0`` and *flags* set to ``NULL``.
.. c:function:: PyObject* PyRun_FileEx(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit)
This is a simplified interface to :c:func:`PyRun_FileExFlags` below, leaving
- *flags* set to *NULL*.
+ *flags* set to ``NULL``.
.. c:function:: PyObject* PyRun_FileFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)
@@ -259,7 +263,7 @@ the same library that the Python runtime is using.
.. c:function:: PyObject* Py_CompileString(const char *str, const char *filename, int start)
This is a simplified interface to :c:func:`Py_CompileStringFlags` below, leaving
- *flags* set to *NULL*.
+ *flags* set to ``NULL``.
.. c:function:: PyObject* Py_CompileStringFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags)
@@ -275,7 +279,7 @@ the same library that the Python runtime is using.
code which can be compiled and should be :const:`Py_eval_input`,
:const:`Py_file_input`, or :const:`Py_single_input`. The filename specified by
*filename* is used to construct the code object and may appear in tracebacks or
- :exc:`SyntaxError` exception messages. This returns *NULL* if the code
+ :exc:`SyntaxError` exception messages. This returns ``NULL`` if the code
cannot be parsed or compiled.
The integer *optimize* specifies the optimization level of the compiler; a
@@ -298,7 +302,7 @@ the same library that the Python runtime is using.
This is a simplified interface to :c:func:`PyEval_EvalCodeEx`, with just
the code object, and global and local variables. The other arguments are
- set to *NULL*.
+ set to ``NULL``.
.. c:function:: PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject *const *args, int argcount, PyObject *const *kws, int kwcount, PyObject *const *defs, int defcount, PyObject *kwdefs, PyObject *closure)
@@ -306,7 +310,7 @@ the same library that the Python runtime is using.
Evaluate a precompiled code object, given a particular environment for its
evaluation. This environment consists of a dictionary of global variables,
a mapping object of local variables, arrays of arguments, keywords and
- defaults, a dictionary of default values for :ref:`keyword-only\
+ defaults, a dictionary of default values for :ref:`keyword-only
` arguments and a closure tuple of cells.
@@ -375,7 +379,7 @@ the same library that the Python runtime is using.
executed, it is passed as ``PyCompilerFlags *flags``. In this case, ``from
__future__ import`` can modify *flags*.
- Whenever ``PyCompilerFlags *flags`` is *NULL*, :attr:`cf_flags` is treated as
+ Whenever ``PyCompilerFlags *flags`` is ``NULL``, :attr:`cf_flags` is treated as
equal to ``0``, and any modification due to ``from __future__ import`` is
discarded. ::
diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst
index 6cb3e33fe843ac..0938ee1928a0b9 100644
--- a/Doc/c-api/weakref.rst
+++ b/Doc/c-api/weakref.rst
@@ -33,9 +33,9 @@ as much as it can.
reference object may be returned. The second parameter, *callback*, can be a
callable object that receives notification when *ob* is garbage collected; it
should accept a single parameter, which will be the weak reference object
- itself. *callback* may also be ``None`` or *NULL*. If *ob* is not a
+ itself. *callback* may also be ``None`` or ``NULL``. If *ob* is not a
weakly-referencable object, or if *callback* is not callable, ``None``, or
- *NULL*, this will return *NULL* and raise :exc:`TypeError`.
+ ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
.. c:function:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
@@ -45,9 +45,9 @@ as much as it can.
existing proxy object may be returned. The second parameter, *callback*, can
be a callable object that receives notification when *ob* is garbage
collected; it should accept a single parameter, which will be the weak
- reference object itself. *callback* may also be ``None`` or *NULL*. If *ob*
+ reference object itself. *callback* may also be ``None`` or ``NULL``. If *ob*
is not a weakly-referencable object, or if *callback* is not callable,
- ``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`.
+ ``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
.. c:function:: PyObject* PyWeakref_GetObject(PyObject *ref)
diff --git a/Doc/conf.py b/Doc/conf.py
index 19a2f7d67ff831..ce2d47f5f8939e 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -14,7 +14,7 @@
# ---------------------
extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest',
- 'pyspecific', 'c_annotations']
+ 'pyspecific', 'c_annotations', 'escape4chm']
# General substitutions.
project = 'Python'
@@ -34,13 +34,22 @@
# By default, highlight as Python 3.
highlight_language = 'python3'
-# Require Sphinx 1.2 for build.
-needs_sphinx = '1.2'
+# Require Sphinx 1.6.6 for build.
+needs_sphinx = "1.6.6"
# Ignore any .rst files in the venv/ directory.
-venvdir = os.getenv('VENVDIR', 'venv')
-exclude_patterns = [venvdir+'/*', 'README.rst']
+exclude_patterns = ['venv/*', 'README.rst']
+venvdir = os.getenv('VENVDIR')
+if venvdir is not None:
+ exclude_patterns.append(venvdir + '/*')
+
+# Disable Docutils smartquotes for several translations
+smartquotes_excludes = {
+ 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], 'builders': ['man', 'text'],
+}
+# Avoid a warning with Sphinx >= 2.0
+master_doc = 'contents'
# Options for HTML output
# -----------------------
diff --git a/Doc/copyright.rst b/Doc/copyright.rst
index 540ff5ef0593af..9b71683155eebe 100644
--- a/Doc/copyright.rst
+++ b/Doc/copyright.rst
@@ -4,7 +4,7 @@ Copyright
Python and this documentation is:
-Copyright © 2001-2018 Python Software Foundation. All rights reserved.
+Copyright © 2001-2023 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
diff --git a/Doc/data/python3.7m.abi b/Doc/data/python3.7m.abi
new file mode 100644
index 00000000000000..d5c17dc4373eac
--- /dev/null
+++ b/Doc/data/python3.7m.abi
@@ -0,0 +1,14618 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 6dc86fc5e54cd4..39061e2c26f566 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -31,29 +31,130 @@
# The parameter names are as they appear in the API manual, not the source
# code.
+PyAnySet_Check:int:::
+PyAnySet_Check:PyObject*:p:0:
+
+PyAnySet_CheckExact:int:::
+PyAnySet_CheckExact:PyObject*:p:0:
+
+PyBool_Check:int:::
+PyBool_Check:PyObject*:o:0:
+
PyBool_FromLong:PyObject*::+1:
-PyBool_FromLong:long:v:0:
+PyBool_FromLong:long:v::
+
+PyBuffer_FillContiguousStrides:void:::
+PyBuffer_FillContiguousStrides:int:ndims::
+PyBuffer_FillContiguousStrides:Py_ssize_t*:shape::
+PyBuffer_FillContiguousStrides:Py_ssize_t*:strides::
+PyBuffer_FillContiguousStrides:int:itemsize::
+PyBuffer_FillContiguousStrides:char:order::
+
+PyBuffer_FillInfo:int:::
+PyBuffer_FillInfo:Py_buffer*:view::
+PyBuffer_FillInfo:PyObject*:exporter:0:
+PyBuffer_FillInfo:void*:buf::
+PyBuffer_FillInfo:Py_ssize_t:len::
+PyBuffer_FillInfo:int:readonly::
+PyBuffer_FillInfo:int:flags::
+
+PyBuffer_IsContiguous:int:::
+PyBuffer_IsContiguous:Py_buffer*:view::
+PyBuffer_IsContiguous:char:order::
+
+PyBuffer_Release:void:::
+PyBuffer_Release:Py_buffer*:view::
+
+PyBuffer_ToContiguous:int:::
+PyBuffer_ToContiguous:void*:buf::
+PyBuffer_ToContiguous:Py_buffer*:src::
+PyBuffer_ToContiguous:Py_ssize_t:len::
+PyBuffer_ToContiguous:char:order::
+
+PyByteArray_AS_STRING:char*:::
+PyByteArray_AS_STRING:PyObject*:bytearray:0:
+
+PyByteArray_AsString:char*:::
+PyByteArray_AsString:PyObject*:bytearray:0:
+
+PyByteArray_Check:int:::
+PyByteArray_Check:PyObject*:o:0:
+
+PyByteArray_CheckExact:int:::
+PyByteArray_CheckExact:PyObject*:o:0:
+
+PyByteArray_Concat:PyObject*::+1:
+PyByteArray_Concat:PyObject*:a:0:
+PyByteArray_Concat:PyObject*:b:0:
+
+PyByteArray_FromObject:PyObject*::+1:
+PyByteArray_FromObject:PyObject*:o:0:
+
+PyByteArray_FromStringAndSize:PyObject*::+1:
+PyByteArray_FromStringAndSize:const char*:string::
+PyByteArray_FromStringAndSize:Py_ssize_t:len::
+
+PyByteArray_GET_SIZE:Py_ssize_t:::
+PyByteArray_GET_SIZE:PyObject*:bytearray:0:
+
+PyByteArray_Resize:int:::
+PyByteArray_Resize:PyObject*:bytearray:0:
+PyByteArray_Resize:Py_ssize_t:len::
+
+PyByteArray_Size:Py_ssize_t:::
+PyByteArray_Size:PyObject*:bytearray:0:
+
+PyBytes_AS_STRING:char*:::
+PyBytes_AS_STRING:PyObject*:string:0:
+
+PyBytes_AsString:char*:::
+PyBytes_AsString:PyObject*:o:0:
+
+PyBytes_AsStringAndSize:int:::
+PyBytes_AsStringAndSize:PyObject*:obj:0:
+PyBytes_AsStringAndSize:char**:buffer::
+PyBytes_AsStringAndSize:Py_ssize_t*:length::
-PyBuffer_FromObject:PyObject*::+1:
-PyBuffer_FromObject:PyObject*:base:+1:
-PyBuffer_FromObject:int:offset::
-PyBuffer_FromObject:int:size::
+PyBytes_Check:int:::
+PyBytes_Check:PyObject*:o:0:
-PyBuffer_FromReadWriteObject:PyObject*::+1:
-PyBuffer_FromReadWriteObject:PyObject*:base:+1:
-PyBuffer_FromReadWriteObject:int:offset::
-PyBuffer_FromReadWriteObject:int:size::
+PyBytes_CheckExact:int:::
+PyBytes_CheckExact:PyObject*:o:0:
-PyBuffer_FromMemory:PyObject*::+1:
-PyBuffer_FromMemory:void*:ptr::
-PyBuffer_FromMemory:int:size::
+PyBytes_Concat:void:::
+PyBytes_Concat:PyObject**:bytes:0:
+PyBytes_Concat:PyObject*:newpart:0:
-PyBuffer_FromReadWriteMemory:PyObject*::+1:
-PyBuffer_FromReadWriteMemory:void*:ptr::
-PyBuffer_FromReadWriteMemory:int:size::
+PyBytes_ConcatAndDel:void:::
+PyBytes_ConcatAndDel:PyObject**:bytes:0:
+PyBytes_ConcatAndDel:PyObject*:newpart:-1:
-PyBuffer_New:PyObject*::+1:
-PyBuffer_New:int:size::
+PyBytes_FromString:PyObject*::+1:
+PyBytes_FromString:const char*:v::
+
+PyBytes_FromStringAndSize:PyObject*::+1:
+PyBytes_FromStringAndSize:const char*:v::
+PyBytes_FromStringAndSize:Py_ssize_t:len::
+
+PyBytes_FromFormat:PyObject*::+1:
+PyBytes_FromFormat:const char*:format::
+PyBytes_FromFormat::...::
+
+PyBytes_FromFormatV:PyObject*::+1:
+PyBytes_FromFormatV:const char*:format::
+PyBytes_FromFormatV:va_list:vargs::
+
+PyBytes_FromObject:PyObject*::+1:
+PyBytes_FromObject:PyObject*:o:0:
+
+PyBytes_GET_SIZE:Py_ssize_t:::
+PyBytes_GET_SIZE:PyObject*:o:0:
+
+PyBytes_Size:Py_ssize_t:::
+PyBytes_Size:PyObject*:o:0:
+
+PyCapsule_CheckExact:int:::
+PyCapsule_CheckExact:PyObject*:p:0:
PyCapsule_GetContext:void *:::
PyCapsule_GetContext:PyObject*:self:0:
@@ -72,6 +173,10 @@ PyCapsule_Import:void *:::
PyCapsule_Import:const char *:name::
PyCapsule_Import:int:no_block::
+PyCapsule_IsValid:int:::
+PyCapsule_IsValid:PyObject*:capsule:0:
+PyCapsule_IsValid:const char*:name::
+
PyCapsule_New:PyObject*::+1:
PyCapsule_New:void*:pointer::
PyCapsule_New:const char *:name::
@@ -93,21 +198,8 @@ PyCapsule_SetPointer:int:::
PyCapsule_SetPointer:PyObject*:self:0:
PyCapsule_SetPointer:void*:pointer::
-
-PyCObject_AsVoidPtr:void*:::
-PyCObject_AsVoidPtr:PyObject*:self:0:
-
-PyCObject_FromVoidPtr:PyObject*::+1:
-PyCObject_FromVoidPtr:void*:cobj::
-PyCObject_FromVoidPtr::void (* destr)(void* )::
-
-PyCObject_FromVoidPtrAndDesc:PyObject*::+1:
-PyCObject_FromVoidPtrAndDesc:void*:cobj::
-PyCObject_FromVoidPtrAndDesc:void*:desc::
-PyCObject_FromVoidPtrAndDesc:void(*)(void*,void*):destr::
-
-PyCObject_GetDesc:void*:::
-PyCObject_GetDesc:PyObject*:self:0:
+PyCell_Check:int:::
+PyCell_Check::ob::
PyCell_New:PyObject*::+1:
PyCell_New:PyObject*:ob:0:
@@ -126,19 +218,118 @@ PyCell_Set:int:::
PyCell_Set:PyObject*:cell:0:
PyCell_Set:PyObject*:value:0:
+PyCallIter_Check:int:::
+PyCallIter_Check::op::
+
PyCallIter_New:PyObject*::+1:
-PyCallIter_New:PyObject*:callable::
-PyCallIter_New:PyObject*:sentinel::
+PyCallIter_New:PyObject*:callable:+1:
+PyCallIter_New:PyObject*:sentinel:+1:
PyCallable_Check:int:::
PyCallable_Check:PyObject*:o:0:
+PyCode_Check:int:::
+PyCode_Check:PyObject*:co:0:
+
+PyCode_GetNumFree:int:::
+PyCode_GetNumFree:PyCodeObject*:co:0:
+
+PyCode_New:PyCodeObject*::+1:
+PyCode_New:int:argcount::
+PyCode_New:int:kwonlyargcount::
+PyCode_New:int:nlocals::
+PyCode_New:int:stacksize::
+PyCode_New:int:flags::
+PyCode_New:PyObject*:code:0:
+PyCode_New:PyObject*:consts:0:
+PyCode_New:PyObject*:names:0:
+PyCode_New:PyObject*:varnames:0:
+PyCode_New:PyObject*:freevars:0:
+PyCode_New:PyObject*:cellvars:0:
+PyCode_New:PyObject*:filename:0:
+PyCode_New:PyObject*:name:0:
+PyCode_New:int:firstlineno::
+PyCode_New:PyObject*:lnotab:0:
+
+PyCode_NewEmpty:PyCodeObject*::+1:
+PyCode_NewEmpty:const char*:filename::
+PyCode_NewEmpty:const char*:funcname::
+PyCode_NewEmpty:int:firstlineno::
+
+PyCodec_Register:int:::
+PyCodec_Register:PyObject*:search_function:+1:
+
+PyCodec_KnownEncoding:int:::
+PyCodec_KnownEncoding:const char*:encoding::
+
+PyCodec_Encode:PyObject*::+1:
+PyCodec_Encode:PyObject*:object:0:
+PyCodec_Encode:const char*:encoding::
+PyCodec_Encode:const char*:errors::
+
+PyCodec_Decode:PyObject*::+1:
+PyCodec_Decode:PyObject*:object:0:
+PyCodec_Decode:const char*:encoding::
+PyCodec_Decode:const char*:errors::
+
+PyCodec_Encoder:PyObject*::+1:
+PyCodec_Encoder:const char*:encoding::
+
+PyCodec_Decoder:PyObject*::+1:
+PyCodec_Decoder:const char*:encoding::
+
+PyCodec_IncrementalEncoder:PyObject*::+1:
+PyCodec_IncrementalEncoder:const char*:encoding::
+PyCodec_IncrementalEncoder:const char*:errors::
+
+PyCodec_IncrementalDecoder:PyObject*::+1:
+PyCodec_IncrementalDecoder:const char*:encoding::
+PyCodec_IncrementalDecoder:const char*:errors::
+
+PyCodec_StreamReader:PyObject*::+1:
+PyCodec_StreamReader:const char*:encoding::
+PyCodec_StreamReader:PyObject*:stream:0:
+PyCodec_StreamReader:const char*:errors::
+
+PyCodec_StreamWriter:PyObject*::+1:
+PyCodec_StreamWriter:const char*:encoding::
+PyCodec_StreamWriter:PyObject*:stream:0:
+PyCodec_StreamWriter:const char*:errors::
+
+PyCodec_RegisterError:int:::
+PyCodec_RegisterError:const char*:name::
+PyCodec_RegisterError:PyObject*:error:+1:
+
+PyCodec_LookupError:PyObject*::+1:
+PyCodec_LookupError:const char*:name::
+
+PyCodec_StrictErrors:PyObject*::null:
+PyCodec_StrictErrors:PyObject*:exc:0:
+
+PyCodec_IgnoreErrors:PyObject*::+1:
+PyCodec_IgnoreErrors:PyObject*:exc:0:
+
+PyCodec_ReplaceErrors:PyObject*::+1:
+PyCodec_ReplaceErrors:PyObject*:exc:0:
+
+PyCodec_XMLCharRefReplaceErrors:PyObject*::+1:
+PyCodec_XMLCharRefReplaceErrors:PyObject*:exc:0:
+
+PyCodec_BackslashReplaceErrors:PyObject*::+1:
+PyCodec_BackslashReplaceErrors:PyObject*:exc:0:
+
+PyCodec_NameReplaceErrors:PyObject*::+1:
+PyCodec_NameReplaceErrors:PyObject*:exc:0:
+
PyComplex_AsCComplex:Py_complex:::
PyComplex_AsCComplex:PyObject*:op:0:
PyComplex_Check:int:::
PyComplex_Check:PyObject*:p:0:
+PyComplex_CheckExact:int:::
+PyComplex_CheckExact:PyObject*:p:0:
+
PyComplex_FromCComplex:PyObject*::+1:
PyComplex_FromCComplex::Py_complex v::
@@ -152,6 +343,53 @@ PyComplex_ImagAsDouble:PyObject*:op:0:
PyComplex_RealAsDouble:double:::
PyComplex_RealAsDouble:PyObject*:op:0:
+PyContext_CheckExact:int:::
+PyContext_CheckExact:PyObject*:o:0:
+
+PyContext_ClearFreeList:int:::
+
+PyContext_Copy:PyObject*::+1:
+PyContext_Copy:PyObject*:ctx:0:
+
+PyContext_CopyCurrent:PyObject*::+1:
+
+PyContext_Enter:int:::
+PyContext_Enter:PyObject*:ctx:+1:
+
+PyContext_Exit:int:::
+PyContext_Exit:PyObject*:ctx:-1:
+
+PyContext_New:PyObject*::+1:
+
+PyContextToken_CheckExact:int:::
+PyContextToken_CheckExact:PyObject*:o:0:
+
+PyContextVar_CheckExact:int:::
+PyContextVar_CheckExact:PyObject*:o:0:
+
+PyContextVar_Get:int:::
+PyContextVar_Get:PyObject*:var:0:
+PyContextVar_Get:PyObject*:default_value:0:
+PyContextVar_Get:PyObject**:value:+1:???
+
+PyContextVar_New:PyObject*::+1:
+PyContextVar_New:const char*:name::
+PyContextVar_New:PyObject*:def:+1:
+
+PyContextVar_Set:PyObject*::+1:
+PyContextVar_Set:PyObject*:var:0:
+PyContextVar_Set:PyObject*:value:+1:
+
+PyContextVar_Reset:int:::
+PyContextVar_Reset:PyObject*:var:0:
+PyContextVar_Reset:PyObject*:token:-1:
+
+PyDate_Check:int:::
+PyDate_Check:PyObject*:ob:0:
+
+PyDate_CheckExact:int:::
+PyDate_CheckExact:PyObject*:ob:0:
+
PyDate_FromDate:PyObject*::+1:
PyDate_FromDate:int:year::
PyDate_FromDate:int:month::
@@ -160,6 +398,12 @@ PyDate_FromDate:int:day::
PyDate_FromTimestamp:PyObject*::+1:
PyDate_FromTimestamp:PyObject*:args:0:
+PyDateTime_Check:int:::
+PyDateTime_Check:PyObject*:ob:0:
+
+PyDateTime_CheckExact:int:::
+PyDateTime_CheckExact:PyObject*:ob:0:
+
PyDateTime_FromDateAndTime:PyObject*::+1:
PyDateTime_FromDateAndTime:int:year::
PyDateTime_FromDateAndTime:int:month::
@@ -169,49 +413,75 @@ PyDateTime_FromDateAndTime:int:minute::
PyDateTime_FromDateAndTime:int:second::
PyDateTime_FromDateAndTime:int:usecond::
+PyDateTime_FromDateAndTimeAndFold:PyObject*::+1:
+PyDateTime_FromDateAndTimeAndFold:int:year::
+PyDateTime_FromDateAndTimeAndFold:int:month::
+PyDateTime_FromDateAndTimeAndFold:int:day::
+PyDateTime_FromDateAndTimeAndFold:int:hour::
+PyDateTime_FromDateAndTimeAndFold:int:minute::
+PyDateTime_FromDateAndTimeAndFold:int:second::
+PyDateTime_FromDateAndTimeAndFold:int:usecond::
+PyDateTime_FromDateAndTimeAndFold:int:fold::
+
PyDateTime_FromTimestamp:PyObject*::+1:
PyDateTime_FromTimestamp:PyObject*:args:0:
+PyDelta_Check:int:::
+PyDelta_Check:PyObject*:ob:0:
+
+PyDelta_CheckExact:int:::
+PyDelta_CheckExact:PyObject*:ob:0:
+
PyDelta_FromDSU:PyObject*::+1:
PyDelta_FromDSU:int:days::
PyDelta_FromDSU:int:seconds::
PyDelta_FromDSU:int:useconds::
PyTimeZone_FromOffset:PyObject*::+1:
-PyTimeZone_FromOffset:PyDateTime_DeltaType*:offset:+1:Reference count not increased if offset is +00:00
+PyTimeZone_FromOffset:PyObject*:offset:+1:Reference count not increased if offset is +00:00
PyTimeZone_FromOffsetAndName:PyObject*::+1:
-PyTimeZone_FromOffsetAndName:PyDateTime_DeltaType*:offset:+1:Reference count not increased if offset is +00:00 and name == NULL
-PyTimeZone_FromOffsetAndName:PyUnicode*:name:+1:
+PyTimeZone_FromOffsetAndName:PyObject*:offset:+1:Reference count not increased if offset is +00:00 and name == NULL
+PyTimeZone_FromOffsetAndName:PyObject*:name:+1:
+
+PyDescr_IsData:int:::
+PyDescr_IsData:PyObject*:descr:0:
PyDescr_NewClassMethod:PyObject*::+1:
-PyDescr_NewClassMethod:PyTypeObject*:type::
+PyDescr_NewClassMethod:PyTypeObject*:type:+1:
PyDescr_NewClassMethod:PyMethodDef*:method::
PyDescr_NewGetSet:PyObject*::+1:
-PyDescr_NewGetSet:PyTypeObject*:type::
+PyDescr_NewGetSet:PyTypeObject*:type:+1:
PyDescr_NewGetSet:PyGetSetDef*:getset::
PyDescr_NewMember:PyObject*::+1:
-PyDescr_NewMember:PyTypeObject*:type::
+PyDescr_NewMember:PyTypeObject*:type:+1:
PyDescr_NewMember:PyMemberDef*:member::
PyDescr_NewMethod:PyObject*::+1:
-PyDescr_NewMethod:PyTypeObject*:type::
+PyDescr_NewMethod:PyTypeObject*:type:+1:
PyDescr_NewMethod:PyMethodDef*:meth::
PyDescr_NewWrapper:PyObject*::+1:
-PyDescr_NewWrapper:PyTypeObject*:type::
+PyDescr_NewWrapper:PyTypeObject*:type:+1:
PyDescr_NewWrapper:struct wrapperbase*:base::
PyDescr_NewWrapper:void*:wrapped::
PyDict_Check:int:::
PyDict_Check:PyObject*:p:0:
+PyDict_CheckExact:int:::
+PyDict_CheckExact:PyObject*:p:0:
+
PyDict_Clear:void:::
PyDict_Clear:PyObject*:p:0:
+PyDict_Contains:int:::
+PyDict_Contains:PyObject*:p:0:
+PyDict_Contains:PyObject*:key:0:
+
PyDict_DelItem:int:::
PyDict_DelItem:PyObject*:p:0:
PyDict_DelItem:PyObject*:key:0:
@@ -220,7 +490,7 @@ PyDict_DelItemString:int:::
PyDict_DelItemString:PyObject*:p:0:
PyDict_DelItemString:const char*:key::
-PyDict_GetItem:PyObject*::0:0
+PyDict_GetItem:PyObject*::0:
PyDict_GetItem:PyObject*:p:0:
PyDict_GetItem:PyObject*:key:0:
@@ -248,9 +518,19 @@ PyDict_New:PyObject*::+1:
PyDict_Copy:PyObject*::+1:
PyDict_Copy:PyObject*:p:0:
+PyDict_Merge:int:::
+PyDict_Merge:PyObject*:a:0:
+PyDict_Merge:PyObject*:b:0:
+PyDict_Merge:int:override::
+
+PyDict_MergeFromSeq2:int:::
+PyDict_MergeFromSeq2:PyObject*:a:0:
+PyDict_MergeFromSeq2:PyObject*:seq2:0:
+PyDict_MergeFromSeq2:int:override::
+
PyDict_Next:int:::
PyDict_Next:PyObject*:p:0:
-PyDict_Next:int:ppos::
+PyDict_Next:Py_ssize_t:ppos::
PyDict_Next:PyObject**:pkey:0:
PyDict_Next:PyObject**:pvalue:0:
@@ -264,8 +544,12 @@ PyDict_SetItemString:PyObject*:p:0:
PyDict_SetItemString:const char*:key::
PyDict_SetItemString:PyObject*:val:+1:
-PyDict_Size:int:::
-PyDict_Size:PyObject*:p::
+PyDict_Size:Py_ssize_t:::
+PyDict_Size:PyObject*:p:0:
+
+PyDict_Update:int:::
+PyDict_Update:PyObject*:a:0:
+PyDict_Update:PyObject*:b:0:
PyDict_Values:PyObject*::+1:
PyDict_Values:PyObject*:p:0:
@@ -289,6 +573,21 @@ PyErr_Fetch:PyObject**:ptype:0:
PyErr_Fetch:PyObject**:pvalue:0:
PyErr_Fetch:PyObject**:ptraceback:0:
+PyErr_Format:PyObject*::null:
+PyErr_Format:PyObject*:exception:+1:
+PyErr_Format:const char*:format::
+PyErr_Format::...::
+
+PyErr_FormatV:PyObject*::null:
+PyErr_FormatV:PyObject*:exception:+1:
+PyErr_FormatV:const char*:format::
+PyErr_FormatV:va_list:vargs::
+
+PyErr_GetExcInfo:void:::
+PyErr_GetExcInfo:PyObject**:ptype:+1:
+PyErr_GetExcInfo:PyObject**:pvalue:+1:
+PyErr_GetExcInfo:PyObject**:ptraceback:+1:
+
PyErr_GivenExceptionMatches:int:::
PyErr_GivenExceptionMatches:PyObject*:given:0:
PyErr_GivenExceptionMatches:PyObject*:exc:0:
@@ -315,27 +614,61 @@ PyErr_Occurred:PyObject*::0:
PyErr_Print:void:::
+PyErr_PrintEx:void:::
+PyErr_PrintEx:int:set_sys_last_vars::
+
+PyErr_ResourceWarning:int:::
+PyErr_ResourceWarning:PyObject*:source:0:
+PyErr_ResourceWarning:Py_ssize_t:stack_level::
+PyErr_ResourceWarning:const char*:format::
+PyErr_ResourceWarning::...::
+
PyErr_Restore:void:::
PyErr_Restore:PyObject*:type:-1:
PyErr_Restore:PyObject*:value:-1:
PyErr_Restore:PyObject*:traceback:-1:
PyErr_SetExcFromWindowsErr:PyObject*::null:
-PyErr_SetExcFromWindowsErr:PyObject*:type:0:
+PyErr_SetExcFromWindowsErr:PyObject*:type:+1:
PyErr_SetExcFromWindowsErr:int:ierr::
PyErr_SetExcFromWindowsErrWithFilename:PyObject*::null:
-PyErr_SetExcFromWindowsErrWithFilename:PyObject*:type:0:
+PyErr_SetExcFromWindowsErrWithFilename:PyObject*:type:+1:
PyErr_SetExcFromWindowsErrWithFilename:int:ierr::
PyErr_SetExcFromWindowsErrWithFilename:const char*:filename::
+PyErr_SetExcFromWindowsErrWithFilenameObject:PyObject*::null:
+PyErr_SetExcFromWindowsErrWithFilenameObject:PyObject*:type:+1:
+PyErr_SetExcFromWindowsErrWithFilenameObject:int:ierr::
+PyErr_SetExcFromWindowsErrWithFilenameObject:PyObject*:filename:+1:
+
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*::null:
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*:type:+1:
+PyErr_SetExcFromWindowsErrWithFilenameObjects:int:ierr::
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*:filename:+1:
+PyErr_SetExcFromWindowsErrWithFilenameObjects:PyObject*:filename2:+1:
+
+PyErr_SetExcInfo:void:::
+PyErr_SetExcInfo:PyObject*:type:0:
+PyErr_SetExcInfo:PyObject*:value:0:
+PyErr_SetExcInfo:PyObject*:traceback:0:
+
PyErr_SetFromErrno:PyObject*::null:
-PyErr_SetFromErrno:PyObject*:type:0:
+PyErr_SetFromErrno:PyObject*:type:+1:
PyErr_SetFromErrnoWithFilename:PyObject*::null:
-PyErr_SetFromErrnoWithFilename:PyObject*:type:0:
+PyErr_SetFromErrnoWithFilename:PyObject*:type:+1:
PyErr_SetFromErrnoWithFilename:const char*:filename::
+PyErr_SetFromErrnoWithFilenameObject:PyObject*::null:
+PyErr_SetFromErrnoWithFilenameObject:PyObject*:type:+1:
+PyErr_SetFromErrnoWithFilenameObject:PyObject*:filenameObject:+1:
+
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*::null:
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*:type:+1:
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*:filenameObject:+1:
+PyErr_SetFromErrnoWithFilenameObjects:PyObject*:filenameObject2:+1:
+
PyErr_SetFromWindowsErr:PyObject*::null:
PyErr_SetFromWindowsErr:int:ierr::
@@ -343,6 +676,16 @@ PyErr_SetFromWindowsErrWithFilename:PyObject*::null:
PyErr_SetFromWindowsErrWithFilename:int:ierr::
PyErr_SetFromWindowsErrWithFilename:const char*:filename::
+PyErr_SetImportError:PyObject*::null:
+PyErr_SetImportError:PyObject*:msg:+1:
+PyErr_SetImportError:PyObject*:name:+1:
+PyErr_SetImportError:PyObject*:path:+1:
+
+PyErr_SetImportErrorSubclass:PyObject*::null:
+PyErr_SetImportErrorSubclass:PyObject*:msg:+1:
+PyErr_SetImportErrorSubclass:PyObject*:name:+1:
+PyErr_SetImportErrorSubclass:PyObject*:path:+1:
+
PyErr_SetInterrupt:void:::
PyErr_SetNone:void:::
@@ -356,31 +699,69 @@ PyErr_SetString:void:::
PyErr_SetString:PyObject*:type:+1:
PyErr_SetString:const char*:message::
-PyErr_Format:PyObject*::null:
-PyErr_Format:PyObject*:exception:+1:
-PyErr_Format:const char*:format::
-PyErr_Format::...::
+PyErr_SyntaxLocation:void:::
+PyErr_SyntaxLocation:const char*:filename::
+PyErr_SyntaxLocation:int:lineno::
-PyErr_FormatV:PyObject*::null:
-PyErr_FormatV:PyObject*:exception:+1:
-PyErr_FormatV:const char*:format::
-PyErr_FormatV:va_list:vargs::
+PyErr_SyntaxLocationEx:void:::
+PyErr_SyntaxLocationEx:const char*:filename::
+PyErr_SyntaxLocationEx:int:lineno::
+PyErr_SyntaxLocationEx:int:col_offset::
+
+PyErr_SyntaxLocationObject:void:::
+PyErr_SyntaxLocationObject:PyObject*:filename:+1:
+PyErr_SyntaxLocationObject:int:lineno::
+PyErr_SyntaxLocationObject:int:col_offset::
PyErr_WarnEx:int:::
PyErr_WarnEx:PyObject*:category:0:
PyErr_WarnEx:const char*:message::
PyErr_WarnEx:Py_ssize_t:stack_level::
+PyErr_WarnExplicit:int:::
+PyErr_WarnExplicit:PyObject*:category:0:
+PyErr_WarnExplicit:const char*:message::
+PyErr_WarnExplicit:const char*:filename::
+PyErr_WarnExplicit:int:lineno::
+PyErr_WarnExplicit:const char*:module::
+PyErr_WarnExplicit:PyObject*:registry:0:
+
+PyErr_WarnExplicitObject:int:::
+PyErr_WarnExplicitObject:PyObject*:category:0:
+PyErr_WarnExplicitObject:PyObject*:message:0:
+PyErr_WarnExplicitObject:PyObject*:filename:0:
+PyErr_WarnExplicitObject:int:lineno::
+PyErr_WarnExplicitObject:PyObject*:module:0:
+PyErr_WarnExplicitObject:PyObject*:registry:0:
+
+PyErr_WarnFormat:int:::
+PyErr_WarnFormat:PyObject*:category:0:
+PyErr_WarnFormat:Py_ssize_t:stack_level::
+PyErr_WarnFormat:const char*:format::
+PyErr_WarnFormat::...::
+
+PyErr_WriteUnraisable:void:::
+PyErr_WriteUnraisable:PyObject*:obj:0:
+
PyEval_AcquireLock:void:::
PyEval_AcquireThread:void:::
PyEval_AcquireThread:PyThreadState*:tstate::
PyEval_GetBuiltins:PyObject*::0:
+
PyEval_GetLocals:PyObject*::0:
+
PyEval_GetGlobals:PyObject*::0:
+
PyEval_GetFrame:PyObject*::0:
+PyEval_GetFuncDesc:const char*:::
+PyEval_GetFuncDesc:PyObject*:func:0:
+
+PyEval_GetFuncName:const char*:::
+PyEval_GetFuncName:PyObject*:func:0:
+
PyEval_InitThreads:void:::
PyEval_ReleaseLock:void:::
@@ -393,61 +774,85 @@ PyEval_RestoreThread:PyThreadState*:tstate::
PyEval_SaveThread:PyThreadState*:::
+PyEval_SetProfile:void:::
+PyEval_SetProfile:Py_tracefunc:func::
+PyEval_SetProfile:PyObject*:obj:+1:
+
+PyEval_SetTrace:void:::
+PyEval_SetTrace:Py_tracefunc:func::
+PyEval_SetTrace:PyObject*:obj:+1:
+
PyEval_EvalCode:PyObject*::+1:
-PyEval_EvalCode:PyCodeObject*:co:0:
+PyEval_EvalCode:PyObject*:co:0:
PyEval_EvalCode:PyObject*:globals:0:
PyEval_EvalCode:PyObject*:locals:0:
-PyException_GetTraceback:PyObject*::+1:
+PyEval_EvalCodeEx:PyObject*::+1:
+PyEval_EvalCodeEx:PyObject*:co:0:
+PyEval_EvalCodeEx:PyObject*:globals:0:
+PyEval_EvalCodeEx:PyObject*:locals:0:
+PyEval_EvalCodeEx:PyObject*const*:args::
+PyEval_EvalCodeEx:int:argcount::
+PyEval_EvalCodeEx:PyObject*const*:kws::
+PyEval_EvalCodeEx:int:kwcount::
+PyEval_EvalCodeEx:PyObject*const*:defs::
+PyEval_EvalCodeEx:int:defcount::
+PyEval_EvalCodeEx:PyObject*:kwdefs:0:
+PyEval_EvalCodeEx:PyObject*:closure:0:
-PyFile_AsFile:FILE*:::
-PyFile_AsFile:PyFileObject*:p:0:
+PyEval_EvalFrame:PyObject*::+1:
+PyEval_EvalFrame:PyFrameObject*:f:0:
-PyFile_Check:int:::
-PyFile_Check:PyObject*:p:0:
+PyEval_EvalFrameEx:PyObject*::+1:
+PyEval_EvalFrameEx:PyFrameObject*:f:0:
+PyEval_EvalFrameEx:int:throwflag::
-PyFile_FromFile:PyObject*::+1:
-PyFile_FromFile:FILE*:fp::
-PyFile_FromFile:const char*:name::
-PyFile_FromFile:const char*:mode::
-PyFile_FromFile:int(*:close)::
+PyEval_MergeCompilerFlags:int:::
+PyEval_MergeCompilerFlags:PyCompilerFlags*:cf::
-PyFile_FromFileEx:PyObject*::+1:
-PyFile_FromFileEx:FILE*:fp::
-PyFile_FromFileEx:const char*:name::
-PyFile_FromFileEx:const char*:mode::
-PyFile_FromFileEx:int(*:close)::
-PyFile_FromFileEx:int:buffering::
-PyFile_FromFileEx:const char*:encoding::
-PyFile_FromFileEx:const char*:newline::
+PyException_GetCause:PyObject*::+1:
+PyException_GetCause:PyObject*:ex:0:
-PyFile_FromString:PyObject*::+1:
-PyFile_FromString:const char*:name::
-PyFile_FromString:const char*:mode::
+PyException_GetContext:PyObject*::+1:
+PyException_GetContext:PyObject*:ex:0:
+
+PyException_GetTraceback:PyObject*::+1:
+PyException_GetTraceback:PyObject*:ex:0:
+
+PyException_SetCause:void:::
+PyException_SetCause:PyObject*:ex:0:
+PyException_SetCause:PyObject*:cause:+1:
+
+PyException_SetContext:void:::
+PyException_SetContext:PyObject*:ex:0:
+PyException_SetContext:PyObject*:ctx:+1:
+
+PyException_SetTraceback:int:::
+PyException_SetTraceback:PyObject*:ex:0:
+PyException_SetTraceback:PyObject*:tb:+1:
+
+PyFile_FromFd:PyObject*::+1:
+PyFile_FromFd:int:fd::
+PyFile_FromFd:const char*:name::
+PyFile_FromFd:const char*:mode::
+PyFile_FromFd:int:buffering::
+PyFile_FromFd:const char*:encoding::
+PyFile_FromFd:const char*:errors::
+PyFile_FromFd:const char*:newline::
+PyFile_FromFd:int:closefd::
PyFile_GetLine:PyObject*::+1:
-PyFile_GetLine:PyObject*:p::
+PyFile_GetLine:PyObject*:p:0:
PyFile_GetLine:int:n::
-PyFile_Name:PyObject*::0:
-PyFile_Name:PyObject*:p:0:
-
-PyFile_SetBufSize:void:::
-PyFile_SetBufSize:PyFileObject*:p:0:
-PyFile_SetBufSize:int:n::
-
-PyFile_SoftSpace:int:::
-PyFile_SoftSpace:PyFileObject*:p:0:
-PyFile_SoftSpace:int:newflag::
-
PyFile_WriteObject:int:::
PyFile_WriteObject:PyObject*:obj:0:
-PyFile_WriteObject:PyFileObject*:p:0:
+PyFile_WriteObject:PyObject*:p:0:
PyFile_WriteObject:int:flags::
PyFile_WriteString:int:::
PyFile_WriteString:const char*:s::
-PyFile_WriteString:PyFileObject*:p:0:
+PyFile_WriteString:PyObject*:p:0:
PyFile_WriteString:int:flags::
PyFloat_AS_DOUBLE:double:::
@@ -459,15 +864,33 @@ PyFloat_AsDouble:PyObject*:pyfloat:0:
PyFloat_Check:int:::
PyFloat_Check:PyObject*:p:0:
+PyFloat_CheckExact:int:::
+PyFloat_CheckExact:PyObject*:p:0:
+
PyFloat_FromDouble:PyObject*::+1:
PyFloat_FromDouble:double:v::
PyFloat_FromString:PyObject*::+1:
PyFloat_FromString:PyObject*:str:0:
+PyFloat_GetInfo:PyObject*::+1:
+PyFloat_GetInfo::void::
+
+PyFrozenSet_Check:int:::
+PyFrozenSet_Check:PyObject*:p:0:
+
+PyFrozenSet_CheckExact:int:::
+PyFrozenSet_CheckExact:PyObject*:p:0:
+
PyFrozenSet_New:PyObject*::+1:
PyFrozenSet_New:PyObject*:iterable:0:
+PyFunction_Check:int:::
+PyFunction_Check:PyObject*:o:0:
+
+PyFunction_GetAnnotations:PyObject*::0:
+PyFunction_GetAnnotations:PyObject*:op:0:
+
PyFunction_GetClosure:PyObject*::0:
PyFunction_GetClosure:PyObject*:op:0:
@@ -492,6 +915,10 @@ PyFunction_NewWithQualName:PyObject*:code:+1:
PyFunction_NewWithQualName:PyObject*:globals:+1:
PyFunction_NewWithQualName:PyObject*:qualname:+1:
+PyFunction_SetAnnotations:int:::
+PyFunction_SetAnnotations:PyObject*:op:0:
+PyFunction_SetAnnotations:PyObject*:annotations:+1:
+
PyFunction_SetClosure:int:::
PyFunction_SetClosure:PyObject*:op:0:
PyFunction_SetClosure:PyObject*:closure:+1:
@@ -500,34 +927,34 @@ PyFunction_SetDefaults:int:::
PyFunction_SetDefaults:PyObject*:op:0:
PyFunction_SetDefaults:PyObject*:defaults:+1:
+PyGen_Check:int:::
+PyGen_Check:PyObject*:ob:0:
+
+PyGen_CheckExact:int:::
+PyGen_CheckExact:PyObject*:ob:0:
+
PyGen_New:PyObject*::+1:
PyGen_New:PyFrameObject*:frame:0:
PyGen_NewWithQualName:PyObject*::+1:
PyGen_NewWithQualName:PyFrameObject*:frame:0:
+PyGen_NewWithQualName:PyObject*:name:0:
+PyGen_NewWithQualName:PyObject*:qualname:0:
+
+PyCoro_CheckExact:int:::
+PyCoro_CheckExact:PyObject*:ob:0:
PyCoro_New:PyObject*::+1:
PyCoro_New:PyFrameObject*:frame:0:
-
-Py_InitModule:PyObject*::0:
-Py_InitModule:const char*:name::
-Py_InitModule:PyMethodDef[]:methods::
-
-Py_InitModule3:PyObject*::0:
-Py_InitModule3:const char*:name::
-Py_InitModule3:PyMethodDef[]:methods::
-Py_InitModule3:const char*:doc::
-
-Py_InitModule4:PyObject*::0:
-Py_InitModule4:const char*:name::
-Py_InitModule4:PyMethodDef[]:methods::
-Py_InitModule4:const char*:doc::
-Py_InitModule4:PyObject*:self::
-Py_InitModule4:int:apiver::usually provided by Py_InitModule or Py_InitModule3
+PyCoro_New:PyObject*:name:0:
+PyCoro_New:PyObject*:qualname:0:
PyImport_AddModule:PyObject*::0:reference borrowed from sys.modules
PyImport_AddModule:const char*:name::
+PyImport_AddModuleObject:PyObject*::0:reference borrowed from sys.modules
+PyImport_AddModuleObject:PyObject*:name:0:
+
PyImport_Cleanup:void:::
PyImport_ExecCodeModule:PyObject*::+1:
@@ -539,8 +966,26 @@ PyImport_ExecCodeModuleEx:const char*:name::
PyImport_ExecCodeModuleEx:PyObject*:co:0:
PyImport_ExecCodeModuleEx:const char*:pathname::
+PyImport_ExecCodeModuleObject:PyObject*::+1:
+PyImport_ExecCodeModuleObject:const char*:name::
+PyImport_ExecCodeModuleObject:PyObject*:co:0:
+PyImport_ExecCodeModuleObject:PyObject*:pathname:0:
+PyImport_ExecCodeModuleObject:PyObject*:cpathname:0:
+
+PyImport_ExecCodeModuleWithPathnames:PyObject*::+1:
+PyImport_ExecCodeModuleWithPathnames:const char*:name::
+PyImport_ExecCodeModuleWithPathnames:PyObject*:co:0:
+PyImport_ExecCodeModuleWithPathnames:const char*:pathname::
+PyImport_ExecCodeModuleWithPathnames:const char*:cpathname::
+
+PyImport_GetImporter:PyObject*::+1:
+PyImport_GetImporter:PyObject*:path:0:
+
PyImport_GetMagicNumber:long:::
+PyImport_GetModule:PyObject*::+1:
+PyImport_GetModule:PyObject*:name:0:
+
PyImport_GetModuleDict:PyObject*::0:
PyImport_Import:PyObject*::+1:
@@ -549,6 +994,9 @@ PyImport_Import:PyObject*:name:0:
PyImport_ImportFrozenModule:int:::
PyImport_ImportFrozenModule:const char*:::
+PyImport_ImportFrozenModuleObject:int:::
+PyImport_ImportFrozenModuleObject:PyObject*::+1:
+
PyImport_ImportModule:PyObject*::+1:
PyImport_ImportModule:const char*:name::
@@ -565,39 +1013,33 @@ PyImport_ImportModuleLevel:PyObject*:locals:0:???
PyImport_ImportModuleLevel:PyObject*:fromlist:0:???
PyImport_ImportModuleLevel:int:level::
-PyImport_ReloadModule:PyObject*::+1:
-PyImport_ReloadModule:PyObject*:m:0:
-
-PyInstance_New:PyObject*::+1:
-PyInstance_New:PyObject*:klass:+1:
-PyInstance_New:PyObject*:arg:0:
-PyInstance_New:PyObject*:kw:0:
-
-PyInstance_NewRaw:PyObject*::+1:
-PyInstance_NewRaw:PyObject*:klass:+1:
-PyInstance_NewRaw:PyObject*:dict:+1:
+PyImport_ImportModuleLevelObject:PyObject*::+1:
+PyImport_ImportModuleLevelObject:PyObject*:name:0:
+PyImport_ImportModuleLevelObject:PyObject*:globals:0:???
+PyImport_ImportModuleLevelObject:PyObject*:locals:0:???
+PyImport_ImportModuleLevelObject:PyObject*:fromlist:0:???
+PyImport_ImportModuleLevelObject:int:level::
-PyInt_AS_LONG:long:::
-PyInt_AS_LONG:PyIntObject*:io:0:
+PyImport_ImportModuleNoBlock:PyObject*::+1:
+PyImport_ImportModuleNoBlock:const char*:name::
-PyInt_AsLong:long:::
-PyInt_AsLong:PyObject*:io:0:
+PyImport_ReloadModule:PyObject*::+1:
+PyImport_ReloadModule:PyObject*:m:0:
-PyInt_Check:int:::
-PyInt_Check:PyObject*:op:0:
+PyIndex_Check:int:::
+PyIndex_Check:PyObject*:o:0:
-PyInt_FromLong:PyObject*::+1:
-PyInt_FromLong:long:ival::
+PyInstanceMethod_Check:int:::
+PyInstanceMethod_Check:PyObject*:o:0:
-PyInt_FromString:PyObject*::+1:
-PyInt_FromString:char*:str:0:
-PyInt_FromString:char**:pend:0:
-PyInt_FromString:int:base:0:
+PyInstanceMethod_Function:PyObject*::0:
+PyInstanceMethod_Function:PyObject*:im:0:
-PyInt_FromSsize_t:PyObject*::+1:
-PyInt_FromSsize_t:Py_ssize_t:ival::
+PyInstanceMethod_GET_FUNCTION:PyObject*::0:
+PyInstanceMethod_GET_FUNCTION:PyObject*:im:0:
-PyInt_GetMax:long:::
+PyInstanceMethod_New:PyObject*::+1:
+PyInstanceMethod_New:PyObject*:func:0:
PyInterpreterState_Clear:void:::
PyInterpreterState_Clear:PyInterpreterState*:interp::
@@ -605,9 +1047,13 @@ PyInterpreterState_Clear:PyInterpreterState*:interp::
PyInterpreterState_Delete:void:::
PyInterpreterState_Delete:PyInterpreterState*:interp::
+PyInterpreterState_GetID:int64_t:::
+PyInterpreterState_GetID:PyInterpreterState*:interp::
+
PyInterpreterState_New:PyInterpreterState*:::
-PyIter_Check:int:o:0:
+PyIter_Check:int:::
+PyIter_Check:PyObject*:o:0:
PyIter_Next:PyObject*::+1:
PyIter_Next:PyObject*:o:0:
@@ -622,50 +1068,53 @@ PyList_AsTuple:PyObject*:list:0:
PyList_Check:int:::
PyList_Check:PyObject*:p:0:
+PyList_CheckExact:int:::
+PyList_CheckExact:PyObject*:p:0:
+
PyList_GET_ITEM:PyObject*::0:
PyList_GET_ITEM:PyObject*:list:0:
-PyList_GET_ITEM:int:i:0:
+PyList_GET_ITEM:Py_ssize_t:i::
-PyList_GET_SIZE:int:::
+PyList_GET_SIZE:Py_ssize_t:::
PyList_GET_SIZE:PyObject*:list:0:
PyList_GetItem:PyObject*::0:
PyList_GetItem:PyObject*:list:0:
-PyList_GetItem:int:index::
+PyList_GetItem:Py_ssize_t:index::
PyList_GetSlice:PyObject*::+1:
PyList_GetSlice:PyObject*:list:0:
-PyList_GetSlice:int:low::
-PyList_GetSlice:int:high::
+PyList_GetSlice:Py_ssize_t:low::
+PyList_GetSlice:Py_ssize_t:high::
PyList_Insert:int:::
PyList_Insert:PyObject*:list:0:
-PyList_Insert:int:index::
+PyList_Insert:Py_ssize_t:index::
PyList_Insert:PyObject*:item:+1:
PyList_New:PyObject*::+1:
-PyList_New:int:len::
+PyList_New:Py_ssize_t:len::
PyList_Reverse:int:::
PyList_Reverse:PyObject*:list:0:
PyList_SET_ITEM:void:::
PyList_SET_ITEM:PyObject*:list:0:
-PyList_SET_ITEM:int:i::
+PyList_SET_ITEM:Py_ssize_t:i::
PyList_SET_ITEM:PyObject*:o:0:
PyList_SetItem:int:::
PyList_SetItem:PyObject*:list:0:
-PyList_SetItem:int:index::
+PyList_SetItem:Py_ssize_t:index::
PyList_SetItem:PyObject*:item:0:
PyList_SetSlice:int:::
PyList_SetSlice:PyObject*:list:0:
-PyList_SetSlice:int:low::
-PyList_SetSlice:int:high::
+PyList_SetSlice:Py_ssize_t:low::
+PyList_SetSlice:Py_ssize_t:high::
PyList_SetSlice:PyObject*:itemlist:0:but increfs its elements?
-PyList_Size:int:::
+PyList_Size:Py_ssize_t:::
PyList_Size:PyObject*:list:0:
PyList_Sort:int:::
@@ -677,12 +1126,44 @@ PyLong_AsDouble:PyObject*:pylong:0:
PyLong_AsLong:long:::
PyLong_AsLong:PyObject*:pylong:0:
+PyLong_AsLongAndOverflow:long:::
+PyLong_AsLongAndOverflow:PyObject*:obj:0:
+PyLong_AsLongAndOverflow:int*:overflow::
+
+PyLong_AsLongLong:long long:::
+PyLong_AsLongLong:PyObject*:obj:0:
+
+PyLong_AsLongLongAndOverflow:long long:::
+PyLong_AsLongLongAndOverflow:PyObject*:obj:0:
+PyLong_AsLongLongAndOverflow:int*:overflow::
+
+PyLong_AsSize_t:size_t:::
+PyLong_AsSize_t:PyObject*:pylong:0:
+
+PyLong_AsSsize_t:Py_ssize_t:::
+PyLong_AsSsize_t:PyObject*:pylong:0:
+
PyLong_AsUnsignedLong:unsigned long:::
PyLong_AsUnsignedLong:PyObject*:pylong:0:
+PyLong_AsUnsignedLongLong:unsigned long long:::
+PyLong_AsUnsignedLongLong:PyObject*:pylong:0:
+
+PyLong_AsUnsignedLongMask:unsigned long:::
+PyLong_AsUnsignedLongMask:PyObject*:obj:0:
+
+PyLong_AsUnsignedLongLongMask:unsigned long long:::
+PyLong_AsUnsignedLongLongMask:PyObject*:obj:0:
+
+PyLong_AsVoidPtr:void*:::
+PyLong_AsVoidPtr:PyObject*:pylong:0:
+
PyLong_Check:int:::
PyLong_Check:PyObject*:p:0:
+PyLong_CheckExact:int:::
+PyLong_CheckExact:PyObject*:p:0:
+
PyLong_FromDouble:PyObject*::+1:
PyLong_FromDouble:double:v::
@@ -695,16 +1176,26 @@ PyLong_FromLongLong:long long:v::
PyLong_FromUnsignedLongLong:PyObject*::+1:
PyLong_FromUnsignedLongLong:unsigned long long:v::
+PyLong_FromSize_t:PyObject*::+1:
+PyLong_FromSize_t:size_t:v::
+
+PyLong_FromSsize_t:PyObject*::+1:
+PyLong_FromSsize_t:Py_ssize_t:v::
+
PyLong_FromString:PyObject*::+1:
PyLong_FromString:const char*:str::
PyLong_FromString:char**:pend::
PyLong_FromString:int:base::
PyLong_FromUnicode:PyObject*::+1:
-PyLong_FromUnicode:Py_UNICODE:u::
-PyLong_FromUnicode:int:length::
+PyLong_FromUnicode:Py_UNICODE*:u::
+PyLong_FromUnicode:Py_ssize_t:length::
PyLong_FromUnicode:int:base::
+PyLong_FromUnicodeObject:PyObject*::+1:
+PyLong_FromUnicodeObject:PyObject*:u:0:
+PyLong_FromUnicodeObject:int:base::
+
PyLong_FromUnsignedLong:PyObject*::+1:
PyLong_FromUnsignedLong:unsignedlong:v::
@@ -740,7 +1231,7 @@ PyMapping_Items:PyObject*:o:0:
PyMapping_Keys:PyObject*::+1:
PyMapping_Keys:PyObject*:o:0:
-PyMapping_Length:int:::
+PyMapping_Length:Py_ssize_t:::
PyMapping_Length:PyObject*:o:0:
PyMapping_SetItemString:int:::
@@ -748,6 +1239,9 @@ PyMapping_SetItemString:PyObject*:o:0:
PyMapping_SetItemString:const char*:key::
PyMapping_SetItemString:PyObject*:v:+1:
+PyMapping_Size:Py_ssize_t:::
+PyMapping_Size:PyObject*:o:0:
+
PyMapping_Values:PyObject*::+1:
PyMapping_Values:PyObject*:o:0:
@@ -759,20 +1253,43 @@ PyMarshal_ReadObjectFromFile:FILE*:file::
PyMarshal_ReadObjectFromString:PyObject*::+1:
PyMarshal_ReadObjectFromString:const char*:string::
-PyMarshal_ReadObjectFromString:int:len::
+PyMarshal_ReadObjectFromString:Py_ssize_t:len::
PyMarshal_WriteObjectToString:PyObject*::+1:
PyMarshal_WriteObjectToString:PyObject*:value:0:
+PyMarshal_WriteObjectToString:int:version::
+
+PyMemoryView_Check:int:::
+PyMemoryView_Check:PyObject*:obj:0:
+
+PyMemoryView_FromBuffer:PyObject*::+1:
+PyMemoryView_FromBuffer:Py_buffer*:view::
+
+PyMemoryView_FromMemory:PyObject*::+1:
+PyMemoryView_FromMemory:char*:mem::
+PyMemoryView_FromMemory:Py_ssize_t:size::
+PyMemoryView_FromMemory:int:flags::
+
+PyMemoryView_FromObject:PyObject*::+1:
+PyMemoryView_FromObject:PyObject*:obj:0:
+
+PyMemoryView_GET_BASE:Py_buffer*:::
+PyMemoryView_GET_BASE:PyObject*:mview:0:
+
+PyMemoryView_GET_BUFFER:Py_buffer*:::
+PyMemoryView_GET_BUFFER:PyObject*:mview:0:
-PyMethod_Class:PyObject*::0:
-PyMethod_Class:PyObject*:im:0:
+PyMemoryView_GetContiguous:PyObject*::+1:
+PyMemoryView_GetContiguous:PyObject*:obj:0:
+PyMemoryView_GetContiguous:int:buffertype::
+PyMemoryView_GetContiguous:char:order::
+
+PyMethod_Check:int:::
+PyMethod_Check:PyObject*:o:0:
PyMethod_Function:PyObject*::0:
PyMethod_Function:PyObject*:im:0:
-PyMethod_GET_CLASS:PyObject*::0:
-PyMethod_GET_CLASS:PyObject*:im:0:
-
PyMethod_GET_FUNCTION:PyObject*::0:
PyMethod_GET_FUNCTION:PyObject*:im:0:
@@ -787,18 +1304,93 @@ PyMethod_New:PyObject*:class:0:
PyMethod_Self:PyObject*::0:
PyMethod_Self:PyObject*:im:0:
+PyModule_AddFunctions:int:::
+PyModule_AddFunctions:PyObject*:module:0:
+PyModule_AddFunctions:PyMethodDef*:functions::
+
+PyModule_AddIntConstant:int:::
+PyModule_AddIntConstant:PyObject*:module:0:
+PyModule_AddIntConstant:const char*:name::
+PyModule_AddIntConstant:long:value::
+
+PyModule_AddIntMacro:int:::
+PyModule_AddIntMacro:PyObject*:module:0:
+PyModule_AddIntMacro::macro::
+
+PyModule_AddObject:int:::
+PyModule_AddObject:PyObject*:module:0:
+PyModule_AddObject:const char*:name::
+PyModule_AddObject:PyObject*:value:+1:
+
+PyModule_AddStringConstant:int:::
+PyModule_AddStringConstant:PyObject*:module:0:
+PyModule_AddStringConstant:const char*:name::
+PyModule_AddStringConstant:const char*:value::
+
+PyModule_AddStringMacro:int:::
+PyModule_AddStringMacro:PyObject*:module:0:
+PyModule_AddStringMacro::macro::
+
+PyModule_Check:int:::
+PyModule_Check:PyObject*:p:0:
+
+PyModule_CheckExact:int:::
+PyModule_CheckExact:PyObject*:p:0:
+
+PyModule_Create:PyObject*::+1:
+PyModule_Create:PyModuleDef*:def::
+
+PyModule_Create2:PyObject*::+1:
+PyModule_Create2:PyModuleDef*:def::
+PyModule_Create2:int:module_api_version::
+
+PyModule_ExecDef:int:::
+PyModule_ExecDef:PyObject*:module:0:
+PyModule_ExecDef:PyModuleDef*:def::
+
+PyModule_FromDefAndSpec:PyObject*::+1:
+PyModule_FromDefAndSpec:PyModuleDef*:def::
+PyModule_FromDefAndSpec:PyObject*:spec:0:
+
+PyModule_FromDefAndSpec2:PyObject*::+1:
+PyModule_FromDefAndSpec2:PyModuleDef*:def::
+PyModule_FromDefAndSpec2:PyObject*:spec:0:
+PyModule_FromDefAndSpec2:int:module_api_version::
+
+PyModule_GetDef:PyModuleDef*::0:
+PyModule_GetDef:PyObject*:module:0:
+
PyModule_GetDict:PyObject*::0:
-PyModule_GetDict::PyObject* module:0:
+PyModule_GetDict:PyObject*:module:0:
PyModule_GetFilename:const char*:::
PyModule_GetFilename:PyObject*:module:0:
+PyModule_GetFilenameObject:PyObject*::+1:
+PyModule_GetFilenameObject:PyObject*:module:0:
+
PyModule_GetName:const char*:::
PyModule_GetName:PyObject*:module:0:
+PyModule_GetNameObject:PyObject*::+1:
+PyModule_GetNameObject:PyObject*:module:0:
+
+PyModule_GetState:void*:::
+PyModule_GetState:PyObject*:module:0:
+
PyModule_New:PyObject*::+1:
PyModule_New::char* name::
+PyModule_NewObject:PyObject*::+1:
+PyModule_NewObject:PyObject*:name:+1:
+
+PyModule_SetDocString:int:::
+PyModule_SetDocString:PyObject*:module:0:
+PyModule_SetDocString:const char*:docstring::
+
+PyModuleDef_Init:PyObject*::0:
+PyModuleDef_Init:PyModuleDef*:def:0:
+
PyNumber_Absolute:PyObject*::+1:
PyNumber_Absolute:PyObject*:o:0:
@@ -810,12 +1402,12 @@ PyNumber_And:PyObject*::+1:
PyNumber_And:PyObject*:o1:0:
PyNumber_And:PyObject*:o2:0:
-PyNumber_Check:PyObject*:o:0:
-PyNumber_Check:int:::
+PyNumber_AsSsize_t:Py_ssize_t:::
+PyNumber_AsSsize_t:PyObject*:o:0:
+PyNumber_AsSsize_t:PyObject*:exc:0:
-PyNumber_Divide:PyObject*::+1:
-PyNumber_Divide:PyObject*:o1:0:
-PyNumber_Divide:PyObject*:o2:0:
+PyNumber_Check:int:::
+PyNumber_Check:PyObject*:o:0:
PyNumber_Divmod:PyObject*::+1:
PyNumber_Divmod:PyObject*:o1:0:
@@ -828,6 +1420,9 @@ PyNumber_FloorDivide:PyObject*::+1:
PyNumber_FloorDivide:PyObject*:v:0:
PyNumber_FloorDivide:PyObject*:w:0:
+PyNumber_Index:PyObject*::+1:
+PyNumber_Index:PyObject*:o:0:
+
PyNumber_InPlaceAdd:PyObject*::+1:
PyNumber_InPlaceAdd:PyObject*:v:0:
PyNumber_InPlaceAdd:PyObject*:w:0:
@@ -836,10 +1431,6 @@ PyNumber_InPlaceAnd:PyObject*::+1:
PyNumber_InPlaceAnd:PyObject*:v:0:
PyNumber_InPlaceAnd:PyObject*:w:0:
-PyNumber_InPlaceDivide:PyObject*::+1:
-PyNumber_InPlaceDivide:PyObject*:v:0:
-PyNumber_InPlaceDivide:PyObject*:w:0:
-
PyNumber_InPlaceFloorDivide:PyObject*::+1:
PyNumber_InPlaceFloorDivide:PyObject*:v:0:
PyNumber_InPlaceFloorDivide:PyObject*:w:0:
@@ -848,6 +1439,10 @@ PyNumber_InPlaceLshift:PyObject*::+1:
PyNumber_InPlaceLshift:PyObject*:v:0:
PyNumber_InPlaceLshift:PyObject*:w:0:
+PyNumber_InPlaceMatrixMultiply:PyObject*::+1:
+PyNumber_InPlaceMatrixMultiply:PyObject*:o1:0:
+PyNumber_InPlaceMatrixMultiply:PyObject*:o2:0:
+
PyNumber_InPlaceMultiply:PyObject*::+1:
PyNumber_InPlaceMultiply:PyObject*:v:0:
PyNumber_InPlaceMultiply:PyObject*:w:0:
@@ -891,6 +1486,10 @@ PyNumber_Lshift:PyObject*::+1:
PyNumber_Lshift:PyObject*:o1:0:
PyNumber_Lshift:PyObject*:o2:0:
+PyNumber_MatrixMultiply:PyObject*::+1:
+PyNumber_MatrixMultiply:PyObject*:o1:0:
+PyNumber_MatrixMultiply:PyObject*:o2:0:
+
PyNumber_Multiply:PyObject*::+1:
PyNumber_Multiply:PyObject*:o1:0:
PyNumber_Multiply:PyObject*:o2:0:
@@ -922,6 +1521,10 @@ PyNumber_Subtract:PyObject*::+1:
PyNumber_Subtract:PyObject*:o1:0:
PyNumber_Subtract:PyObject*:o2:0:
+PyNumber_ToBase:PyObject*::+1:
+PyNumber_ToBase:PyObject*:n:0:
+PyNumber_ToBase:int:base::
+
PyNumber_TrueDivide:PyObject*::+1:
PyNumber_TrueDivide:PyObject*:v:0:
PyNumber_TrueDivide:PyObject*:w:0:
@@ -933,9 +1536,38 @@ PyNumber_Xor:PyObject*:o2:0:
PyObject_AsFileDescriptor:int:::
PyObject_AsFileDescriptor:PyObject*:o:0:
+PyOS_AfterFork:void:::
+
+PyOS_AfterFork_Child:void:::
+
+PyOS_AfterFork_Parent:void:::
+
+PyOS_BeforeFork:void:::
+
PyOS_FSPath:PyObject*::+1:
PyOS_FSPath:PyObject*:path:0:
+PyObject_ASCII:PyObject*::+1:
+PyObject_ASCII:PyObject*:o:0:
+
+PyObject_AsCharBuffer:int:::
+PyObject_AsCharBuffer:PyObject*:obj:0:
+PyObject_AsCharBuffer:const char**:buffer::
+PyObject_AsCharBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_AsReadBuffer:int:::
+PyObject_AsReadBuffer:PyObject*:obj:0:
+PyObject_AsReadBuffer:const void**:buffer::
+PyObject_AsReadBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_AsWriteBuffer:int:::
+PyObject_AsWriteBuffer:PyObject*:obj:0:
+PyObject_AsWriteBuffer:void**:buffer::
+PyObject_AsWriteBuffer:Py_ssize_t*:buffer_len::
+
+PyObject_Bytes:PyObject*::+1:
+PyObject_Bytes:PyObject*:o:0:
+
PyObject_Call:PyObject*::+1:
PyObject_Call:PyObject*:callable_object:0:
PyObject_Call:PyObject*:args:0:
@@ -965,14 +1597,11 @@ PyObject_CallObject:PyObject*::+1:
PyObject_CallObject:PyObject*:callable_object:0:
PyObject_CallObject:PyObject*:args:0:
-PyObject_Cmp:int:::
-PyObject_Cmp:PyObject*:o1:0:
-PyObject_Cmp:PyObject*:o2:0:
-PyObject_Cmp:int*:result::
+PyObject_CheckBuffer:int:::
+PyObject_CheckBuffer:PyObject*:obj:0:
-PyObject_Compare:int:::
-PyObject_Compare:PyObject*:o1:0:
-PyObject_Compare:PyObject*:o2:0:
+PyObject_CheckReadBuffer:int:::
+PyObject_CheckReadBuffer:PyObject*:o:0:
PyObject_DelAttr:int:::
PyObject_DelAttr:PyObject*:o:0:
@@ -989,6 +1618,47 @@ PyObject_DelItem:PyObject*:key:0:
PyObject_Dir:PyObject*::+1:
PyObject_Dir:PyObject*:o:0:
+PyObject_GC_Del:void:::
+PyObject_GC_Del:void*:op::
+
+PyObject_GC_New:TYPE*::+1:
+PyObject_GC_New::TYPE::
+PyObject_GC_New:PyTypeObject*:type:0:
+
+PyObject_GC_NewVar:TYPE*::+1:
+PyObject_GC_NewVar::TYPE::
+PyObject_GC_NewVar:PyTypeObject*:type:0:
+PyObject_GC_NewVar:Py_ssize_t:size::
+
+PyObject_GC_Resize:TYPE*::0:
+PyObject_GC_Resize::TYPE::
+PyObject_GC_Resize:PyVarObject*:op:0:
+PyObject_GC_Resize:Py_ssize_t:newsize::
+
+PyObject_GC_Track:void:::
+PyObject_GC_Track:PyObject*:op:0:
+
+PyObject_GC_UnTrack:void:::
+PyObject_GC_UnTrack:void*:op::
+
+PyObject_GenericGetAttr:PyObject*::+1:
+PyObject_GenericGetAttr:PyObject*:o:0:
+PyObject_GenericGetAttr:PyObject*:name:0:
+
+PyObject_GenericGetDict:PyObject*::+1:
+PyObject_GenericGetDict:PyObject*:o:0:
+PyObject_GenericGetDict:void*:context::
+
+PyObject_GenericSetAttr:int:::
+PyObject_GenericSetAttr:PyObject*:o:0:
+PyObject_GenericSetAttr:PyObject*:name:0:
+PyObject_GenericSetAttr:PyObject*:value:+1:
+
+PyObject_GenericSetDict:int:::
+PyObject_GenericSetDict:PyObject*:o:0:
+PyObject_GenericSetDict:PyObject*:value:+1:
+PyObject_GenericSetDict:void*:context::
+
PyObject_GetAttr:PyObject*::+1:
PyObject_GetAttr:PyObject*:o:0:
PyObject_GetAttr:PyObject*:attr_name:0:
@@ -997,6 +1667,11 @@ PyObject_GetAttrString:PyObject*::+1:
PyObject_GetAttrString:PyObject*:o:0:
PyObject_GetAttrString:const char*:attr_name::
+PyObject_GetBuffer:int:::
+PyObject_GetBuffer:PyObject*:exporter:0:
+PyObject_GetBuffer:Py_buffer*:view::
+PyObject_GetBuffer:int:flags::
+
PyObject_GetItem:PyObject*::+1:
PyObject_GetItem:PyObject*:o:0:
PyObject_GetItem:PyObject*:key:0:
@@ -1010,30 +1685,59 @@ PyObject_HasAttr:PyObject*:attr_name:0:
PyObject_HasAttrString:int:::
PyObject_HasAttrString:PyObject*:o:0:
-PyObject_HasAttrString:const char*:attr_name:0:
+PyObject_HasAttrString:const char*:attr_name::
PyObject_Hash:int:::
PyObject_Hash:PyObject*:o:0:
+PyObject_HashNotImplemented:Py_hash_t:::
+PyObject_HashNotImplemented:PyObject*:o:0:
+
+PyObject_IsInstance:int:::
+PyObject_IsInstance:PyObject*:inst:0:
+PyObject_IsInstance:PyObject*:cls:0:
+
+PyObject_IsSubclass:int:::
+PyObject_IsSubclass:PyObject*:derived:0:
+PyObject_IsSubclass:PyObject*:cls:0:
+
PyObject_IsTrue:int:::
PyObject_IsTrue:PyObject*:o:0:
PyObject_Init:PyObject*::0:
PyObject_Init:PyObject*:op:0:
+PyObject_Init:PyTypeObject*:type:0:
PyObject_InitVar:PyVarObject*::0:
PyObject_InitVar:PyVarObject*:op:0:
-PyObject_Length:int:::
+PyObject_Length:Py_ssize_t:::
PyObject_Length:PyObject*:o:0:
+PyObject_LengthHint:Py_ssize_t:::
+PyObject_LengthHint:PyObject*:o:0:
+PyObject_LengthHint:Py_ssize_t:default::
+
PyObject_NEW:PyObject*::+1:
+PyObject_NEW::TYPE::
+PyObject_NEW:PyTypeObject*:type:0:
PyObject_New:PyObject*::+1:
+PyObject_New::TYPE::
+PyObject_New:PyTypeObject*:type:0:
PyObject_NEW_VAR:PyObject*::+1:
+PyObject_NEW_VAR::TYPE::
+PyObject_NEW_VAR:PyTypeObject*:type:0:
+PyObject_NEW_VAR:Py_ssize_t:size::
PyObject_NewVar:PyObject*::+1:
+PyObject_NewVar::TYPE::
+PyObject_NewVar:PyTypeObject*:type:0:
+PyObject_NewVar:Py_ssize_t:size::
+
+PyObject_Not:int:::
+PyObject_Not:PyObject*:o:0:
PyObject_Print:int:::
PyObject_Print:PyObject*:o:0:
@@ -1068,28 +1772,65 @@ PyObject_SetItem:PyObject*:o:0:
PyObject_SetItem:PyObject*:key:0:
PyObject_SetItem:PyObject*:v:+1:
+PyObject_Size:Py_ssize_t:::
+PyObject_Size:PyObject*:o:0:
+
PyObject_Str:PyObject*::+1:
PyObject_Str:PyObject*:o:0:
PyObject_Type:PyObject*::+1:
PyObject_Type:PyObject*:o:0:
-PyObject_Unicode:PyObject*::+1:
-PyObject_Unicode:PyObject*:o:0:
+PyObject_TypeCheck:int:::
+PyObject_TypeCheck:PyObject*:o:0:
+PyObject_TypeCheck:PyTypeObject*:type:0:
PyParser_SimpleParseFile:struct _node*:::
PyParser_SimpleParseFile:FILE*:fp::
PyParser_SimpleParseFile:const char*:filename::
PyParser_SimpleParseFile:int:start::
+PyParser_SimpleParseFileFlags:struct _node*:::
+PyParser_SimpleParseFileFlags:FILE*:fp::
+PyParser_SimpleParseFileFlags:const char*:filename::
+PyParser_SimpleParseFileFlags:int:start::
+PyParser_SimpleParseFileFlags:int:flags::
+
PyParser_SimpleParseString:struct _node*:::
PyParser_SimpleParseString:const char*:str::
PyParser_SimpleParseString:int:start::
+PyParser_SimpleParseStringFlags:struct _node*:::
+PyParser_SimpleParseStringFlags:const char*:str::
+PyParser_SimpleParseStringFlags:int:start::
+PyParser_SimpleParseStringFlags:int:flags::
+
+PyParser_SimpleParseStringFlagsFilename:struct _node*:::
+PyParser_SimpleParseStringFlagsFilename:const char*:str::
+PyParser_SimpleParseStringFlagsFilename:const char*:filename::
+PyParser_SimpleParseStringFlagsFilename:int:start::
+PyParser_SimpleParseStringFlagsFilename:int:flags::
+
PyRun_AnyFile:int:::
PyRun_AnyFile:FILE*:fp::
PyRun_AnyFile:const char*:filename::
+PyRun_AnyFileFlags:int:::
+PyRun_AnyFileFlags:FILE*:fp::
+PyRun_AnyFileFlags:const char*:filename::
+PyRun_AnyFileFlags:PyCompilerFlags*:flags::
+
+PyRun_AnyFileEx:int:::
+PyRun_AnyFileEx:FILE*:fp::
+PyRun_AnyFileEx:const char*:filename::
+PyRun_AnyFileEx:int:closeit::
+
+PyRun_AnyFileExFlags:int:::
+PyRun_AnyFileExFlags:FILE*:fp::
+PyRun_AnyFileExFlags:const char*:filename::
+PyRun_AnyFileExFlags:int:closeit::
+PyRun_AnyFileExFlags:PyCompilerFlags*:flags::
+
PyRun_File:PyObject*::+1:??? -- same as eval_code2()
PyRun_File:FILE*:fp::
PyRun_File:const char*:filename::
@@ -1126,17 +1867,42 @@ PyRun_InteractiveLoop:int:::
PyRun_InteractiveLoop:FILE*:fp::
PyRun_InteractiveLoop:const char*:filename::
+PyRun_InteractiveLoopFlags:int:::
+PyRun_InteractiveLoopFlags:FILE*:fp::
+PyRun_InteractiveLoopFlags:const char*:filename::
+PyRun_InteractiveLoopFlags:PyCompilerFlags*:flags::
+
PyRun_InteractiveOne:int:::
PyRun_InteractiveOne:FILE*:fp::
PyRun_InteractiveOne:const char*:filename::
+PyRun_InteractiveOneFlags:int:::
+PyRun_InteractiveOneFlags:FILE*:fp::
+PyRun_InteractiveOneFlags:const char*:filename::
+PyRun_InteractiveOneFlags:PyCompilerFlags*:flags::
+
PyRun_SimpleFile:int:::
PyRun_SimpleFile:FILE*:fp::
PyRun_SimpleFile:const char*:filename::
+PyRun_SimpleFileEx:int:::
+PyRun_SimpleFileEx:FILE*:fp::
+PyRun_SimpleFileEx:const char*:filename::
+PyRun_SimpleFileEx:int:closeit::
+
+PyRun_SimpleFileExFlags:int:::
+PyRun_SimpleFileExFlags:FILE*:fp::
+PyRun_SimpleFileExFlags:const char*:filename::
+PyRun_SimpleFileExFlags:int:closeit::
+PyRun_SimpleFileExFlags:PyCompilerFlags*:flags::
+
PyRun_SimpleString:int:::
PyRun_SimpleString:const char*:command::
+PyRun_SimpleStringFlags:int:::
+PyRun_SimpleStringFlags:const char*:command::
+PyRun_SimpleStringFlags:PyCompilerFlags*:flags::
+
PyRun_String:PyObject*::+1:??? -- same as eval_code2()
PyRun_String:const char*:str::
PyRun_String:int:start::
@@ -1150,6 +1916,9 @@ PyRun_StringFlags:PyObject*:globals:0:
PyRun_StringFlags:PyObject*:locals:0:
PyRun_StringFlags:PyCompilerFlags*:flags::
+PySeqIter_Check:int:::
+PySeqIter_Check::op::
+
PySeqIter_New:PyObject*::+1:
PySeqIter_New:PyObject*:seq::
@@ -1160,18 +1929,22 @@ PySequence_Concat:PyObject*::+1:
PySequence_Concat:PyObject*:o1:0:
PySequence_Concat:PyObject*:o2:0:
-PySequence_Count:int:::
+PySequence_Contains:int:::
+PySequence_Contains:PyObject*:o:0:
+PySequence_Contains:PyObject*:value:0:
+
+PySequence_Count:Py_ssize_t:::
PySequence_Count:PyObject*:o:0:
PySequence_Count:PyObject*:value:0:
PySequence_DelItem:int:::
PySequence_DelItem:PyObject*:o:0:
-PySequence_DelItem:int:i::
+PySequence_DelItem:Py_ssize_t:i::
PySequence_DelSlice:int:::
PySequence_DelSlice:PyObject*:o:0:
-PySequence_DelSlice:int:i1::
-PySequence_DelSlice:int:i2::
+PySequence_DelSlice:Py_ssize_t:i1::
+PySequence_DelSlice:Py_ssize_t:i2::
PySequence_Fast:PyObject*::+1:
PySequence_Fast:PyObject*:v:0:
@@ -1179,22 +1952,28 @@ PySequence_Fast:const char*:m::
PySequence_Fast_GET_ITEM:PyObject*::0:
PySequence_Fast_GET_ITEM:PyObject*:o:0:
-PySequence_Fast_GET_ITEM:int:i::
+PySequence_Fast_GET_ITEM:Py_ssize_t:i::
+
+PySequence_Fast_GET_SIZE:Py_ssize_t:::
+PySequence_Fast_GET_SIZE:PyObject*:o:0:
+
+PySequence_Fast_ITEMS:PyObject**:::
+PySequence_Fast_ITEMS:PyObject*:o:0:
PySequence_GetItem:PyObject*::+1:
PySequence_GetItem:PyObject*:o:0:
-PySequence_GetItem:int:i::
+PySequence_GetItem:Py_ssize_t:i::
PySequence_GetSlice:PyObject*::+1:
PySequence_GetSlice:PyObject*:o:0:
-PySequence_GetSlice:int:i1::
-PySequence_GetSlice:int:i2::
+PySequence_GetSlice:Py_ssize_t:i1::
+PySequence_GetSlice:Py_ssize_t:i2::
PySequence_In:int:::
PySequence_In:PyObject*:o:0:
PySequence_In:PyObject*:value:0:
-PySequence_Index:int:::
+PySequence_Index:Py_ssize_t:::
PySequence_Index:PyObject*:o:0:
PySequence_Index:PyObject*:value:0:
@@ -1208,22 +1987,25 @@ PySequence_InPlaceRepeat:PyObject*:o:0:
PySequence_ITEM:PyObject*::+1:
PySequence_ITEM:PyObject*:o:0:
-PySequence_ITEM:int:i::
+PySequence_ITEM:Py_ssize_t:i::
PySequence_Repeat:PyObject*::+1:
PySequence_Repeat:PyObject*:o:0:
-PySequence_Repeat:int:count::
+PySequence_Repeat:Py_ssize_t:count::
PySequence_SetItem:int:::
PySequence_SetItem:PyObject*:o:0:
-PySequence_SetItem:int:i::
+PySequence_SetItem:Py_ssize_t:i::
PySequence_SetItem:PyObject*:v:+1:
PySequence_SetSlice:int:::
PySequence_SetSlice:PyObject*:o:0:
-PySequence_SetSlice:int:i1::
-PySequence_SetSlice:int:i2::
-PySequence_SetSlice:PyObject*:v:+1:
+PySequence_SetSlice:Py_ssize_t:i1::
+PySequence_SetSlice:Py_ssize_t:i2::
+PySequence_SetSlice:PyObject*:v:0:
+
+PySequence_Size:Py_ssize_t:::
+PySequence_Size:PyObject*:o:0:
PySequence_List:PyObject*::+1:
PySequence_List:PyObject*:o:0:
@@ -1231,9 +2013,15 @@ PySequence_List:PyObject*:o:0:
PySequence_Tuple:PyObject*::+1:
PySequence_Tuple:PyObject*:o:0:
-PySet_Append:int:::
-PySet_Append:PyObject*:set:0:
-PySet_Append:PyObject*:key:+1:
+PySet_Add:int:::
+PySet_Add:PyObject*:set:0:
+PySet_Add:PyObject*:key:+1:
+
+PySet_Check:int:::
+PySet_Check:PyObject*:p:0:
+
+PySet_Clear:int:::
+PySet_Clear:PyObject*:set:0:
PySet_Contains:int:::
PySet_Contains:PyObject*:anyset:0:
@@ -1243,117 +2031,128 @@ PySet_Discard:int:::
PySet_Discard:PyObject*:set:0:
PySet_Discard:PyObject*:key:-1:no effect if key not found
+PySet_GET_SIZE:Py_ssize_t:::
+PySet_GET_SIZE:PyObject*:anyset:0:
+
PySet_New:PyObject*::+1:
PySet_New:PyObject*:iterable:0:
PySet_Pop:PyObject*::+1:or returns NULL and raises KeyError if set is empty
PySet_Pop:PyObject*:set:0:
-PySet_Size:int:::
+PySet_Size:Py_ssize_t:::
PySet_Size:PyObject*:anyset:0:
+PySignal_SetWakeupFd:int:::
+PySignal_SetWakeupFd:int:fd::
+
+PySlice_AdjustIndices:Py_ssize_t:::
+PySlice_AdjustIndices:Py_ssize_t:length::
+PySlice_AdjustIndices:Py_ssize_t*:start::
+PySlice_AdjustIndices:Py_ssize_t*:stop::
+PySlice_AdjustIndices:Py_ssize_t*:step::
+
PySlice_Check:int:::
PySlice_Check:PyObject*:ob:0:
+PySlice_GetIndices:int:::
+PySlice_GetIndices:PyObject*:slice:0:
+PySlice_GetIndices:Py_ssize_t:length::
+PySlice_GetIndices:Py_ssize_t*:start::
+PySlice_GetIndices:Py_ssize_t*:stop::
+PySlice_GetIndices:Py_ssize_t*:step::
+
+PySlice_GetIndicesEx:int:::
+PySlice_GetIndicesEx:PyObject*:slice:0:
+PySlice_GetIndicesEx:Py_ssize_t:length::
+PySlice_GetIndicesEx:Py_ssize_t*:start::
+PySlice_GetIndicesEx:Py_ssize_t*:stop::
+PySlice_GetIndicesEx:Py_ssize_t*:step::
+PySlice_GetIndicesEx:Py_ssize_t*:slicelength::
+
PySlice_New:PyObject*::+1:
PySlice_New:PyObject*:start:0:
PySlice_New:PyObject*:stop:0:
PySlice_New:PyObject*:step:0:
-PyString_AS_STRING:const char*:::
-PyString_AS_STRING:PyObject*:string:0:
-
-PyString_AsDecodedObject:PyObject*::+1:
-PyString_AsDecodedObject:PyObject*:str:0:
-PyString_AsDecodedObject:const char*:encoding::
-PyString_AsDecodedObject:const char*:errors::
-
-PyString_AsEncodedObject:PyObject*::+1:
-PyString_AsEncodedObject:PyObject*:str:0:
-PyString_AsEncodedObject:const char*:encoding::
-PyString_AsEncodedObject:const char*:errors::
+PySlice_Unpack:int:::
+PySlice_Unpack:PyObject*:slice:0:
+PySlice_Unpack:Py_ssize_t*:start::
+PySlice_Unpack:Py_ssize_t*:stop::
+PySlice_Unpack:Py_ssize_t*:step::
-PyString_AsString:const char*:::
-PyString_AsString:PyObject*:string:0:
+PyState_AddModule:int:::
+PyState_AddModule:PyObject*:module:+1:
+PyState_AddModule:PyModuleDef*:def::
-PyString_AsStringAndSize:int:::
-PyString_AsStringAndSize:PyObject*:obj:0:
-PyString_AsStringAndSize:char**:buffer::
-PyString_AsStringAndSize:int*:length::
+PyState_FindModule:PyObject*::0:
+PyState_FindModule:PyModuleDef*:def::
-PyString_Check:int:::
-PyString_Check:PyObject*:o:0:
+PyState_RemoveModule:int:::
+PyState_RemoveModule:PyModuleDef*:def::
-PyString_Concat:void:::
-PyString_Concat:PyObject**:string:0:??? -- replaces w/ new string or NULL
-PyString_Concat:PyObject*:newpart:0:
+PyStructSequence_GET_ITEM:PyObject*::0:
+PyStructSequence_GET_ITEM:PyObject*:p:0:
+PyStructSequence_GET_ITEM:Py_ssize_t:pos::
-PyString_ConcatAndDel:void:::
-PyString_ConcatAndDel:PyObject**:string:0:??? -- replaces w/ new string or NULL
-PyString_ConcatAndDel:PyObject*:newpart:-1:
+PyStructSequence_GetItem:PyObject*::0:
+PyStructSequence_GetItem:PyObject*:p:0:
+PyStructSequence_GetItem:Py_ssize_t:pos::
-PyString_Format:PyObject*::+1:
-PyString_Format:PyObject*:format:0:
-PyString_Format:PyObject*:args:0:
+PyStructSequence_InitType:void:::
+PyStructSequence_InitType:PyTypeObject*:type:+1:
+PyStructSequence_InitType:PyStructSequence_Desc*:desc::
-PyString_FromString:PyObject*::+1:
-PyString_FromString:const char*:v::
+PyStructSequence_InitType2:int:::
+PyStructSequence_InitType2:PyTypeObject*:type:+1:
+PyStructSequence_InitType2:PyStructSequence_Desc*:desc::
-PyString_FromStringAndSize:PyObject*::+1:
-PyString_FromStringAndSize:const char*:v::
-PyString_FromStringAndSize:int:len::
+PyStructSequence_New:PyObject*::+1:
+PyStructSequence_New:PyTypeObject*:type:0:
-PyString_FromFormat:PyObject*::+1:
-PyString_FromFormat:const char*:format::
-PyString_FromFormat::...::
+PyStructSequence_NewType:PyTypeObject*::+1:
+PyStructSequence_NewType:PyStructSequence_Desc*:desc::
-PyString_FromFormatV:PyObject*::+1:
-PyString_FromFormatV:const char*:format::
-PyString_FromFormatV:va_list:vargs::
+PyStructSequence_SET_ITEM:void:::
+PyStructSequence_SET_ITEM:PyObject*:p:0:
+PyStructSequence_SET_ITEM:Py_ssize_t*:pos::
+PyStructSequence_SET_ITEM:PyObject*:o:0:
-PyString_GET_SIZE:int:::
-PyString_GET_SIZE:PyObject*:string:0:
-
-PyString_InternFromString:PyObject*::+1:
-PyString_InternFromString:const char*:v::
-
-PyString_InternInPlace:void:::
-PyString_InternInPlace:PyObject**:string:+1:???
-
-PyString_Size:int:::
-PyString_Size:PyObject*:string:0:
-
-PyString_Decode:PyObject*::+1:
-PyString_Decode:const char*:s::
-PyString_Decode:int:size::
-PyString_Decode:const char*:encoding::
-PyString_Decode:const char*:errors::
-
-PyString_Encode:PyObject*::+1:
-PyString_Encode:const char*:s::
-PyString_Encode:int:size::
-PyString_Encode:const char*:encoding::
-PyString_Encode:const char*:errors::
-
-PyString_AsEncodedString:PyObject*::+1:
-PyString_AsEncodedString:PyObject*:str::
-PyString_AsEncodedString:const char*:encoding::
-PyString_AsEncodedString:const char*:errors::
+PyStructSequence_SetItem:void:::
+PyStructSequence_SetItem:PyObject*:p:0:
+PyStructSequence_SetItem:Py_ssize_t:pos::
+PyStructSequence_SetItem:PyObject*:o:0:
PySys_AddWarnOption:void:::
-PySys_AddWarnOption:const char*:s::
+PySys_AddWarnOption:const wchar_t*:s::
+
+PySys_AddWarnOptionUnicode:void:::
+PySys_AddWarnOptionUnicode:PyObject*:unicode:0:
PySys_AddXOption:void:::
PySys_AddXOption:const wchar_t*:s::
+PySys_FormatStderr:void:::
+PySys_FormatStderr:const char*:format::
+PySys_FormatStderr::...::
+
+PySys_FormatStdout:void:::
+PySys_FormatStdout:const char*:format::
+PySys_FormatStdout::...::
+
PySys_GetObject:PyObject*::0:
PySys_GetObject:const char*:name::
PySys_GetXOptions:PyObject*::0:
-PySys_SetArgv:int:::
+PySys_SetArgv:void:::
PySys_SetArgv:int:argc::
-PySys_SetArgv:char**:argv::
+PySys_SetArgv:wchar_t**:argv::
+
+PySys_SetArgvEx:void:::
+PySys_SetArgvEx:int:argc::
+PySys_SetArgvEx:wchar_t**:argv::
+PySys_SetArgvEx:int:updatepath::
PySys_SetObject:int:::
PySys_SetObject:const char*:name::
@@ -1363,9 +2162,11 @@ PySys_ResetWarnOptions:void:::
PySys_WriteStdout:void:::
PySys_WriteStdout:const char*:format::
+PySys_WriteStdout::...::
PySys_WriteStderr:void:::
PySys_WriteStderr:const char*:format::
+PySys_WriteStderr::...::
PyThreadState_Clear:void:::
PyThreadState_Clear:PyThreadState*:tstate::
@@ -1380,75 +2181,189 @@ PyThreadState_GetDict:PyObject*::0:
PyThreadState_New:PyThreadState*:::
PyThreadState_New:PyInterpreterState*:interp::
+PyThreadState_SetAsyncExc:int:::
+PyThreadState_SetAsyncExc:unsigned long:id::
+PyThreadState_SetAsyncExc:PyObject*:exc:+1:
+
PyThreadState_Swap:PyThreadState*:::
PyThreadState_Swap:PyThreadState*:tstate::
+PyThread_tss_alloc:Py_tss_t*:::
+
+PyThread_tss_create:int:::
+PyThread_tss_create:Py_tss_t*:key::
+
+PyThread_tss_delete:void:::
+PyThread_tss_delete:Py_tss_t*:key::
+
+PyThread_tss_free:void:::
+PyThread_tss_free:Py_tss_t*:key::
+
+PyThread_tss_get:void*:::
+PyThread_tss_get:Py_tss_t*:key::
+
+PyThread_tss_is_created:int:::
+PyThread_tss_is_created:Py_tss_t*:key::
+
+PyThread_tss_set:int:::
+PyThread_tss_set:Py_tss_t*:key::
+PyThread_tss_set:void*:value::
+
+PyTime_Check:int:::
+PyTime_Check:PyObject*:ob:0:
+
+PyTime_CheckExact:int:::
+PyTime_CheckExact:PyObject*:ob:0:
+
PyTime_FromTime:PyObject*::+1:
PyTime_FromTime:int:hour::
PyTime_FromTime:int:minute::
PyTime_FromTime:int:second::
PyTime_FromTime:int:usecond::
+PyTime_FromTimeAndFold:PyObject*::+1:
+PyTime_FromTimeAndFold:int:hour::
+PyTime_FromTimeAndFold:int:minute::
+PyTime_FromTimeAndFold:int:second::
+PyTime_FromTimeAndFold:int:usecond::
+PyTime_FromTimeAndFold:int:fold::
+
+PyTraceMalloc_Track:int:::
+PyTraceMalloc_Track:unsigned int:domain::
+PyTraceMalloc_Track:uintptr_t:ptr::
+PyTraceMalloc_Track:size_t:size::
+
+PyTraceMalloc_Untrack:int:::
+PyTraceMalloc_Untrack:unsigned int:domain::
+PyTraceMalloc_Untrack:uintptr_t:ptr::
+
PyTuple_Check:int:::
PyTuple_Check:PyObject*:p:0:
+PyTuple_CheckExact:int:::
+PyTuple_CheckExact:PyObject*:p:0:
+
PyTuple_GET_ITEM:PyObject*::0:
-PyTuple_GET_ITEM:PyTupleObject*:p:0:
-PyTuple_GET_ITEM:int:pos::
+PyTuple_GET_ITEM:PyObject*:p:0:
+PyTuple_GET_ITEM:Py_ssize_t:pos::
PyTuple_GetItem:PyObject*::0:
-PyTuple_GetItem:PyTupleObject*:p:0:
-PyTuple_GetItem:int:pos::
+PyTuple_GetItem:PyObject*:p:0:
+PyTuple_GetItem:Py_ssize_t:pos::
+
+PyTuple_GET_SIZE:Py_ssize_t:::
+PyTuple_GET_SIZE:PyObject*:p:0:
PyTuple_GetSlice:PyObject*::+1:
-PyTuple_GetSlice:PyTupleObject*:p:0:
-PyTuple_GetSlice:int:low::
-PyTuple_GetSlice:int:high::
+PyTuple_GetSlice:PyObject*:p:0:
+PyTuple_GetSlice:Py_ssize_t:low::
+PyTuple_GetSlice:Py_ssize_t:high::
PyTuple_New:PyObject*::+1:
-PyTuple_New:int:len::
+PyTuple_New:Py_ssize_t:len::
PyTuple_Pack:PyObject*::+1:
-PyTuple_Pack:int:len::
+PyTuple_Pack:Py_ssize_t:len::
PyTuple_Pack:PyObject*:...:0:
PyTuple_SET_ITEM:void:::
-PyTuple_SET_ITEM:PyTupleObject*:p:0:
-PyTuple_SET_ITEM:int:pos::
+PyTuple_SET_ITEM:PyObject*:p:0:
+PyTuple_SET_ITEM:Py_ssize_t:pos::
PyTuple_SET_ITEM:PyObject*:o:0:
PyTuple_SetItem:int:::
-PyTuple_SetItem:PyTupleObject*:p:0:
-PyTuple_SetItem:int:pos::
+PyTuple_SetItem:PyObject*:p:0:
+PyTuple_SetItem:Py_ssize_t:pos::
PyTuple_SetItem:PyObject*:o:0:
-PyTuple_Size:int:::
-PyTuple_Size:PyTupleObject*:p:0:
+PyTuple_Size:Py_ssize_t:::
+PyTuple_Size:PyObject*:p:0:
+
+PyType_Check:int:::
+PyType_Check:PyObject*:o:0:
+
+PyType_CheckExact:int:::
+PyType_CheckExact:PyObject*:o:0:
+
+PyType_FromSpec:PyObject*::+1:
+PyType_FromSpec:PyType_Spec*:spec::
+
+PyType_FromSpecWithBases:PyObject*::+1:
+PyType_FromSpecWithBases:PyType_Spec*:spec::
+PyType_FromSpecWithBases:PyObject*:bases:0:
PyType_GenericAlloc:PyObject*::+1:
PyType_GenericAlloc:PyObject*:type:0:
-PyType_GenericAlloc:int:nitems:0:
+PyType_GenericAlloc:Py_ssize_t:nitems::
PyType_GenericNew:PyObject*::+1:
PyType_GenericNew:PyObject*:type:0:
PyType_GenericNew:PyObject*:args:0:
PyType_GenericNew:PyObject*:kwds:0:
+PyType_GetFlags:unsigned long:::
+PyType_GetFlags:PyTypeObject*:type:0:
+
+PyType_GetSlot:void*:::
+PyType_GetSlot:PyTypeObject*:type:0:
+PyType_GetSlot:int:slot::
+
+PyType_HasFeature:int:::
+PyType_HasFeature:PyTypeObject*:o:0:
+PyType_HasFeature:int:feature::
+
+PyType_IS_GC:int:::
+PyType_IS_GC:PyTypeObject*:o:0:
+
+PyType_IsSubtype:int:::
+PyType_IsSubtype:PyTypeObject*:a:0:
+PyType_IsSubtype:PyTypeObject*:b:0:
+
+PyType_Modified:void:::
+PyType_Modified:PyTypeObject*:type:0:
+
+PyType_Ready:int:::
+PyType_Ready:PyTypeObject*:type:0:
+
+PyUnicode_1BYTE_DATA:Py_UCS1*:::
+PyUnicode_1BYTE_DATA:PyObject*:o:0:
+
PyUnicode_Check:int:::
PyUnicode_Check:PyObject*:o:0:
-PyUnicode_GET_SIZE:int:::
+PyUnicode_CheckExact:int:::
+PyUnicode_CheckExact:PyObject*:o:0:
+
+PyUnicode_DATA:void*:::
+PyUnicode_DATA:PyObject*:o:0:
+
+PyUnicode_GET_LENGTH:Py_ssize_t:::
+PyUnicode_GET_LENGTH:PyObject*:o:0:
+
+PyUnicode_GET_SIZE:Py_ssize_t:::
PyUnicode_GET_SIZE:PyObject*:o:0:
-PyUnicode_GET_DATA_SIZE:int:::
+PyUnicode_GET_DATA_SIZE:Py_ssize_t:::
PyUnicode_GET_DATA_SIZE:PyObject*:o:0:
+PyUnicode_KIND:int:::
+PyUnicode_KIND:PyObject*:o:0:
+
+PyUnicode_MAX_CHAR_VALUE::::
+PyUnicode_MAX_CHAR_VALUE:PyObject*:o:0:
+
PyUnicode_AS_UNICODE:Py_UNICODE*:::
PyUnicode_AS_UNICODE:PyObject*:o:0:
PyUnicode_AS_DATA:const char*:::
PyUnicode_AS_DATA:PyObject*:o:0:
+Py_UNICODE_ISALNUM:int:::
+Py_UNICODE_ISALNUM:Py_UNICODE:ch::
+
+Py_UNICODE_ISALPHA:int:::
+Py_UNICODE_ISALPHA:Py_UNICODE:ch::
+
Py_UNICODE_ISSPACE:int:::
Py_UNICODE_ISSPACE:Py_UNICODE:ch::
@@ -1473,6 +2388,9 @@ Py_UNICODE_ISDIGIT:Py_UNICODE:ch::
Py_UNICODE_ISNUMERIC:int:::
Py_UNICODE_ISNUMERIC:Py_UNICODE:ch::
+Py_UNICODE_ISPRINTABLE:int:::
+Py_UNICODE_ISPRINTABLE:Py_UNICODE:ch::
+
Py_UNICODE_TOLOWER:Py_UNICODE:::
Py_UNICODE_TOLOWER:Py_UNICODE:ch::
@@ -1493,150 +2411,210 @@ Py_UNICODE_TONUMERIC:Py_UNICODE:ch::
PyUnicode_FromUnicode:PyObject*::+1:
PyUnicode_FromUnicode:const Py_UNICODE*:u::
-PyUnicode_FromUnicode:int:size::
+PyUnicode_FromUnicode:Py_ssize_t:size::
PyUnicode_AsUnicode:Py_UNICODE*:::
-PyUnicode_AsUnicode:PyObject :*unicode:0:
+PyUnicode_AsUnicode:PyObject*:unicode:0:
-PyUnicode_GetSize:int:::
-PyUnicode_GetSize:PyObject :*unicode:0:
+PyUnicode_TransformDecimalToASCII:PyObject*::+1:
+PyUnicode_TransformDecimalToASCII:Py_UNICODE*:s::
+PyUnicode_TransformDecimalToASCII:Py_ssize_t:size::
+
+PyUnicode_AsUnicodeAndSize:Py_UNICODE*:::
+PyUnicode_AsUnicodeAndSize:PyObject*:unicode:0:
+PyUnicode_AsUnicodeAndSize:Py_ssize_t*:size::
+
+PyUnicode_AsUnicodeCopy:Py_UNICODE*:::
+PyUnicode_AsUnicodeCopy:PyObject*:unicode:0:
+
+PyUnicode_GetSize:Py_ssize_t:::
+PyUnicode_GetSize:PyObject*:unicode:0:
PyUnicode_FromObject:PyObject*::+1:
-PyUnicode_FromObject:PyObject*:*obj:0:
+PyUnicode_FromObject:PyObject*:obj:0:
PyUnicode_FromEncodedObject:PyObject*::+1:
-PyUnicode_FromEncodedObject:PyObject*:*obj:0:
+PyUnicode_FromEncodedObject:PyObject*:obj:0:
PyUnicode_FromEncodedObject:const char*:encoding::
PyUnicode_FromEncodedObject:const char*:errors::
PyUnicode_FromWideChar:PyObject*::+1:
PyUnicode_FromWideChar:const wchar_t*:w::
-PyUnicode_FromWideChar:int:size::
+PyUnicode_FromWideChar:Py_ssize_t:size::
-PyUnicode_AsWideChar:int:::
+PyUnicode_AsWideChar:Py_ssize_t:::
PyUnicode_AsWideChar:PyObject*:*unicode:0:
PyUnicode_AsWideChar:wchar_t*:w::
-PyUnicode_AsWideChar:int:size::
+PyUnicode_AsWideChar:Py_ssize_t:size::
+
+PyUnicode_AsWideCharString:wchar_t*:::
+PyUnicode_AsWideCharString:PyObject*:unicode:0:
+PyUnicode_AsWideCharString:Py_ssize_t*:size::
PyUnicode_Decode:PyObject*::+1:
PyUnicode_Decode:const char*:s::
-PyUnicode_Decode:int:size::
+PyUnicode_Decode:Py_ssize_t:size::
PyUnicode_Decode:const char*:encoding::
PyUnicode_Decode:const char*:errors::
PyUnicode_DecodeUTF16Stateful:PyObject*::+1:
PyUnicode_DecodeUTF16Stateful:const char*:s::
-PyUnicode_DecodeUTF16Stateful:int:size::
+PyUnicode_DecodeUTF16Stateful:Py_ssize_t:size::
PyUnicode_DecodeUTF16Stateful:const char*:errors::
PyUnicode_DecodeUTF16Stateful:int*:byteorder::
-PyUnicode_DecodeUTF16Stateful:int*:consumed::
+PyUnicode_DecodeUTF16Stateful:Py_ssize_t*:consumed::
PyUnicode_DecodeUTF8Stateful:PyObject*::+1:
PyUnicode_DecodeUTF8Stateful:const char*:s::
-PyUnicode_DecodeUTF8Stateful:int:size::
+PyUnicode_DecodeUTF8Stateful:Py_ssize_t:size::
PyUnicode_DecodeUTF8Stateful:const char*:errors::
-PyUnicode_DecodeUTF8Stateful:int*:consumed::
+PyUnicode_DecodeUTF8Stateful:Py_ssize_t*:consumed::
PyUnicode_Encode:PyObject*::+1:
PyUnicode_Encode:const Py_UNICODE*:s::
-PyUnicode_Encode:int:size::
+PyUnicode_Encode:Py_ssize_t:size::
PyUnicode_Encode:const char*:encoding::
PyUnicode_Encode:const char*:errors::
PyUnicode_AsEncodedString:PyObject*::+1:
-PyUnicode_AsEncodedString:PyObject*:unicode::
+PyUnicode_AsEncodedString:PyObject*:unicode:0:
PyUnicode_AsEncodedString:const char*:encoding::
PyUnicode_AsEncodedString:const char*:errors::
+PyUnicode_DecodeUTF7:PyObject*::+1:
+PyUnicode_DecodeUTF7:const char*:s::
+PyUnicode_DecodeUTF7:Py_ssize_t:size::
+PyUnicode_DecodeUTF7:const char*:errors::
+
+PyUnicode_DecodeUTF7Stateful:PyObject*::+1:
+PyUnicode_DecodeUTF7Stateful:const char*:s::
+PyUnicode_DecodeUTF7Stateful:Py_ssize_t:size::
+PyUnicode_DecodeUTF7Stateful:const char*:errors::
+PyUnicode_DecodeUTF7Stateful:Py_ssize_t*:consumed::
+
+PyUnicode_EncodeUTF7:PyObject*::+1:
+PyUnicode_EncodeUTF7:const Py_UNICODE*:s::
+PyUnicode_EncodeUTF7:Py_ssize_t:size::
+PyUnicode_EncodeUTF7:int:base64SetO::
+PyUnicode_EncodeUTF7:int:base64WhiteSpace::
+PyUnicode_EncodeUTF7:const char*:errors::
+
PyUnicode_DecodeUTF8:PyObject*::+1:
PyUnicode_DecodeUTF8:const char*:s::
-PyUnicode_DecodeUTF8:int:size::
+PyUnicode_DecodeUTF8:Py_ssize_t:size::
PyUnicode_DecodeUTF8:const char*:errors::
PyUnicode_EncodeUTF8:PyObject*::+1:
PyUnicode_EncodeUTF8:const Py_UNICODE*:s::
-PyUnicode_EncodeUTF8:int:size::
+PyUnicode_EncodeUTF8:Py_ssize_t:size::
PyUnicode_EncodeUTF8:const char*:errors::
PyUnicode_AsUTF8String:PyObject*::+1:
-PyUnicode_AsUTF8String:PyObject*:unicode::
+PyUnicode_AsUTF8String:PyObject*:unicode:0:
+
+PyUnicode_AsUTF8AndSize:const char*:::
+PyUnicode_AsUTF8AndSize:PyObject*:unicode:0:
+PyUnicode_AsUTF8AndSize:Py_ssize_t*:size:0:
+
+PyUnicode_AsUTF8:const char*:::
+PyUnicode_AsUTF8:PyObject*:unicode:0:
PyUnicode_DecodeUTF16:PyObject*::+1:
PyUnicode_DecodeUTF16:const char*:s::
-PyUnicode_DecodeUTF16:int:size::
+PyUnicode_DecodeUTF16:Py_ssize_t:size::
PyUnicode_DecodeUTF16:const char*:errors::
PyUnicode_DecodeUTF16:int*:byteorder::
PyUnicode_EncodeUTF16:PyObject*::+1:
PyUnicode_EncodeUTF16:const Py_UNICODE*:s::
-PyUnicode_EncodeUTF16:int:size::
+PyUnicode_EncodeUTF16:Py_ssize_t:size::
PyUnicode_EncodeUTF16:const char*:errors::
PyUnicode_EncodeUTF16:int:byteorder::
PyUnicode_AsUTF16String:PyObject*::+1:
-PyUnicode_AsUTF16String:PyObject*:unicode::
+PyUnicode_AsUTF16String:PyObject*:unicode:0:
+
+PyUnicode_DecodeUTF32:PyObject*::+1:
+PyUnicode_DecodeUTF32:const char*:s::
+PyUnicode_DecodeUTF32:Py_ssize_t:size::
+PyUnicode_DecodeUTF32:const char*:errors::
+PyUnicode_DecodeUTF32:int*:byteorder::
+
+PyUnicode_DecodeUTF32Stateful:PyObject*::+1:
+PyUnicode_DecodeUTF32Stateful:const char*:s::
+PyUnicode_DecodeUTF32Stateful:Py_ssize_t:size::
+PyUnicode_DecodeUTF32Stateful:const char*:errors::
+PyUnicode_DecodeUTF32Stateful:int*:byteorder::
+PyUnicode_DecodeUTF32Stateful:Py_ssize_t*:consumed::
+
+PyUnicode_AsUTF32String:PyObject*::+1:
+PyUnicode_AsUTF32String:PyObject*:unicode:0:
+
+PyUnicode_EncodeUTF32:PyObject*::+1:
+PyUnicode_EncodeUTF32:const Py_UNICODE*:s::
+PyUnicode_EncodeUTF32:Py_ssize_t:size::
+PyUnicode_EncodeUTF32:const char*:errors::
+PyUnicode_EncodeUTF32:int:byteorder::
PyUnicode_DecodeUnicodeEscape:PyObject*::+1:
PyUnicode_DecodeUnicodeEscape:const char*:s::
-PyUnicode_DecodeUnicodeEscape:int:size::
+PyUnicode_DecodeUnicodeEscape:Py_ssize_t:size::
PyUnicode_DecodeUnicodeEscape:const char*:errors::
PyUnicode_EncodeUnicodeEscape:PyObject*::+1:
PyUnicode_EncodeUnicodeEscape:const Py_UNICODE*:s::
-PyUnicode_EncodeUnicodeEscape:int:size::
-PyUnicode_EncodeUnicodeEscape:const char*:errors::
+PyUnicode_EncodeUnicodeEscape:Py_ssize_t:size::
PyUnicode_AsUnicodeEscapeString:PyObject*::+1:
-PyUnicode_AsUnicodeEscapeString:PyObject*:unicode::
+PyUnicode_AsUnicodeEscapeString:PyObject*:unicode:0:
PyUnicode_DecodeRawUnicodeEscape:PyObject*::+1:
PyUnicode_DecodeRawUnicodeEscape:const char*:s::
-PyUnicode_DecodeRawUnicodeEscape:int:size::
+PyUnicode_DecodeRawUnicodeEscape:Py_ssize_t:size::
PyUnicode_DecodeRawUnicodeEscape:const char*:errors::
PyUnicode_EncodeRawUnicodeEscape:PyObject*::+1:
PyUnicode_EncodeRawUnicodeEscape:const Py_UNICODE*:s::
-PyUnicode_EncodeRawUnicodeEscape:int:size::
-PyUnicode_EncodeRawUnicodeEscape:const char*:errors::
+PyUnicode_EncodeRawUnicodeEscape:Py_ssize_t:size::
PyUnicode_AsRawUnicodeEscapeString:PyObject*::+1:
-PyUnicode_AsRawUnicodeEscapeString:PyObject*:unicode::
+PyUnicode_AsRawUnicodeEscapeString:PyObject*:unicode:0:
PyUnicode_DecodeLatin1:PyObject*::+1:
PyUnicode_DecodeLatin1:const char*:s::
-PyUnicode_DecodeLatin1:int:size::
+PyUnicode_DecodeLatin1:Py_ssize_t:size::
PyUnicode_DecodeLatin1:const char*:errors::
PyUnicode_EncodeLatin1:PyObject*::+1:
PyUnicode_EncodeLatin1:const Py_UNICODE*:s::
-PyUnicode_EncodeLatin1:int:size::
+PyUnicode_EncodeLatin1:Py_ssize_t:size::
PyUnicode_EncodeLatin1:const char*:errors::
PyUnicode_AsLatin1String:PyObject*::+1:
-PyUnicode_AsLatin1String:PyObject*:unicode::
+PyUnicode_AsLatin1String:PyObject*:unicode:0:
PyUnicode_DecodeASCII:PyObject*::+1:
PyUnicode_DecodeASCII:const char*:s::
-PyUnicode_DecodeASCII:int:size::
+PyUnicode_DecodeASCII:Py_ssize_t:size::
PyUnicode_DecodeASCII:const char*:errors::
PyUnicode_EncodeASCII:PyObject*::+1:
PyUnicode_EncodeASCII:const Py_UNICODE*:s::
-PyUnicode_EncodeASCII:int:size::
+PyUnicode_EncodeASCII:Py_ssize_t:size::
PyUnicode_EncodeASCII:const char*:errors::
PyUnicode_AsASCIIString:PyObject*::+1:
-PyUnicode_AsASCIIString:PyObject*:unicode::
+PyUnicode_AsASCIIString:PyObject*:unicode:0:
PyUnicode_DecodeCharmap:PyObject*::+1:
PyUnicode_DecodeCharmap:const char*:s::
-PyUnicode_DecodeCharmap:int:size::
+PyUnicode_DecodeCharmap:Py_ssize_t:size::
PyUnicode_DecodeCharmap:PyObject*:mapping:0:
PyUnicode_DecodeCharmap:const char*:errors::
PyUnicode_EncodeCharmap:PyObject*::+1:
PyUnicode_EncodeCharmap:const Py_UNICODE*:s::
-PyUnicode_EncodeCharmap:int:size::
+PyUnicode_EncodeCharmap:Py_ssize_t:size::
PyUnicode_EncodeCharmap:PyObject*:mapping:0:
PyUnicode_EncodeCharmap:const char*:errors::
@@ -1646,22 +2624,33 @@ PyUnicode_AsCharmapString:PyObject*:mapping:0:
PyUnicode_TranslateCharmap:PyObject*::+1:
PyUnicode_TranslateCharmap:const Py_UNICODE*:s::
-PyUnicode_TranslateCharmap:int:size::
-PyUnicode_TranslateCharmap:PyObject*:table:0:
+PyUnicode_TranslateCharmap:Py_ssize_t:size::
+PyUnicode_TranslateCharmap:PyObject*:mapping:0:
PyUnicode_TranslateCharmap:const char*:errors::
PyUnicode_DecodeMBCS:PyObject*::+1:
PyUnicode_DecodeMBCS:const char*:s::
-PyUnicode_DecodeMBCS:int:size::
+PyUnicode_DecodeMBCS:Py_ssize_t:size::
PyUnicode_DecodeMBCS:const char*:errors::
+PyUnicode_DecodeMBCSStateful:PyObject*::+1:
+PyUnicode_DecodeMBCSStateful:const char*:s::
+PyUnicode_DecodeMBCSStateful:Py_ssize_t:size::
+PyUnicode_DecodeMBCSStateful:const char*:errors::
+PyUnicode_DecodeMBCSStateful:Py_ssize_t*:consumed::
+
+PyUnicode_EncodeCodePage:PyObject*::+1:
+PyUnicode_EncodeCodePage:int:code_page::
+PyUnicode_EncodeCodePage:PyObject*:unicode:0:
+PyUnicode_EncodeCodePage:const char*:errors::
+
PyUnicode_EncodeMBCS:PyObject*::+1:
PyUnicode_EncodeMBCS:const Py_UNICODE*:s::
-PyUnicode_EncodeMBCS:int:size::
+PyUnicode_EncodeMBCS:Py_ssize_t:size::
PyUnicode_EncodeMBCS:const char*:errors::
PyUnicode_AsMBCSString:PyObject*::+1:
-PyUnicode_AsMBCSString:PyObject*:unicode::
+PyUnicode_AsMBCSString:PyObject*:unicode:0:
PyUnicode_Concat:PyObject*::+1:
PyUnicode_Concat:PyObject*:left:0:
@@ -1670,11 +2659,11 @@ PyUnicode_Concat:PyObject*:right:0:
PyUnicode_Split:PyObject*::+1:
PyUnicode_Split:PyObject*:left:0:
PyUnicode_Split:PyObject*:right:0:
-PyUnicode_Split:int:maxsplit::
+PyUnicode_Split:Py_ssize_t:maxsplit::
PyUnicode_Splitlines:PyObject*::+1:
PyUnicode_Splitlines:PyObject*:s:0:
-PyUnicode_Splitlines:int:maxsplit::
+PyUnicode_Splitlines:int:keepend::
PyUnicode_Translate:PyObject*::+1:
PyUnicode_Translate:PyObject*:str:0:
@@ -1685,36 +2674,52 @@ PyUnicode_Join:PyObject*::+1:
PyUnicode_Join:PyObject*:separator:0:
PyUnicode_Join:PyObject*:seq:0:
-PyUnicode_Tailmatch:int:::
+PyUnicode_Tailmatch:Py_ssize_t:::
PyUnicode_Tailmatch:PyObject*:str:0:
PyUnicode_Tailmatch:PyObject*:substr:0:
-PyUnicode_Tailmatch:int:start::
-PyUnicode_Tailmatch:int:end::
+PyUnicode_Tailmatch:Py_ssize_t:start::
+PyUnicode_Tailmatch:Py_ssize_t:end::
PyUnicode_Tailmatch:int:direction::
-PyUnicode_Find:int:::
+PyUnicode_Find:Py_ssize_t:::
PyUnicode_Find:PyObject*:str:0:
PyUnicode_Find:PyObject*:substr:0:
-PyUnicode_Find:int:start::
-PyUnicode_Find:int:end::
+PyUnicode_Find:Py_ssize_t:start::
+PyUnicode_Find:Py_ssize_t:end::
PyUnicode_Find:int:direction::
-PyUnicode_Count:int:::
+PyUnicode_FindChar:Py_ssize_t:::
+PyUnicode_FindChar:PyObject*:str:0:
+PyUnicode_FindChar:Py_UCS4:ch::
+PyUnicode_FindChar:Py_ssize_t:start::
+PyUnicode_FindChar:Py_ssize_t:end::
+PyUnicode_FindChar:int:direction::
+
+PyUnicode_Count:Py_ssize_t:::
PyUnicode_Count:PyObject*:str:0:
PyUnicode_Count:PyObject*:substr:0:
-PyUnicode_Count:int:start::
-PyUnicode_Count:int:end::
+PyUnicode_Count:Py_ssize_t:start::
+PyUnicode_Count:Py_ssize_t:end::
PyUnicode_Replace:PyObject*::+1:
PyUnicode_Replace:PyObject*:str:0:
PyUnicode_Replace:PyObject*:substr:0:
PyUnicode_Replace:PyObject*:replstr:0:
-PyUnicode_Replace:int:maxcount::
+PyUnicode_Replace:Py_ssize_t:maxcount::
PyUnicode_Compare:int:::
PyUnicode_Compare:PyObject*:left:0:
PyUnicode_Compare:PyObject*:right:0:
+PyUnicode_CompareWithASCIIString:int:::
+PyUnicode_CompareWithASCIIString:PyObject*:uni:0:
+PyUnicode_CompareWithASCIIString:const char*:string::
+
+PyUnicode_RichCompare:PyObject*::+1:
+PyUnicode_RichCompare:PyObject*:left:0:
+PyUnicode_RichCompare:PyObject*:right:0:
+PyUnicode_RichCompare:int:op::
+
PyUnicode_Format:PyObject*::+1:
PyUnicode_Format:PyObject*:format:0:
PyUnicode_Format:PyObject*:args:0:
@@ -1723,6 +2728,185 @@ PyUnicode_Contains:int:::
PyUnicode_Contains:PyObject*:container:0:
PyUnicode_Contains:PyObject*:element:0:
+PyUnicode_InternInPlace:void:::
+PyUnicode_InternInPlace:PyObject**:string:+1:
+
+PyUnicode_InternFromString:PyObject*::+1:
+PyUnicode_InternFromString:const char*:v::
+
+PyUnicode_New:PyObject*::+1:
+PyUnicode_New:Py_ssize_t:size::
+PyUnicode_New:Py_UCS4:maxchar::
+
+PyUnicode_FromKindAndData:PyObject*::+1:
+PyUnicode_FromKindAndData:int:kind::
+PyUnicode_FromKindAndData:const void*:buffer::
+PyUnicode_FromKindAndData:Py_ssize_t:size::
+
+PyUnicode_FromStringAndSize:PyObject*::+1:
+PyUnicode_FromStringAndSize:const char*:u::
+PyUnicode_FromStringAndSize:Py_ssize_t:size::
+
+PyUnicode_FromString:PyObject*::+1:
+PyUnicode_FromString:const char*:u::
+
+PyUnicode_FromFormat:PyObject*::+1:
+PyUnicode_FromFormat:const char*:format::
+PyUnicode_FromFormat::...::
+
+PyUnicode_FromFormatV:PyObject*::+1:
+PyUnicode_FromFormatV:const char*:format::
+PyUnicode_FromFormatV:va_list:args::
+
+PyUnicode_GetLength:Py_ssize_t:::
+PyUnicode_GetLength:PyObject*:unicode:0:
+
+PyUnicode_CopyCharacters:Py_ssize_t:::
+PyUnicode_CopyCharacters:PyObject*:to:0:
+PyUnicode_CopyCharacters:Py_ssize_t:to_start::
+PyUnicode_CopyCharacters:PyObject*:from:0:
+PyUnicode_CopyCharacters:Py_ssize_t:from_start::
+PyUnicode_CopyCharacters:Py_ssize_t:how_many::
+
+PyUnicode_Fill:Py_ssize_t:::
+PyUnicode_Fill:PyObject*:unicode:0:
+PyUnicode_Fill:Py_ssize_t:start::
+PyUnicode_Fill:Py_ssize_t:length::
+PyUnicode_Fill:Py_UCS4:fill_char::
+
+PyUnicode_READ:Py_UCS4:::
+PyUnicode_READ:int:kind::
+PyUnicode_READ:void*:data::
+PyUnicode_READ:Py_ssize_t:index::
+
+PyUnicode_READ_CHAR:Py_UCS4:::
+PyUnicode_READ_CHAR:PyObject*:o:0:
+PyUnicode_READ_CHAR:Py_ssize_t:index::
+
+PyUnicode_ReadChar:Py_UCS4:::
+PyUnicode_ReadChar:PyObject*:unicode:0:
+PyUnicode_ReadChar:Py_ssize_t:index::
+
+PyUnicode_WRITE:void:::
+PyUnicode_WRITE:int:kind::
+PyUnicode_WRITE:void*:data::
+PyUnicode_WRITE:Py_ssize_t:index::
+PyUnicode_WRITE:Py_UCS4:value::
+
+PyUnicode_WriteChar:int:::
+PyUnicode_WriteChar:PyObject*:unicode:0:
+PyUnicode_WriteChar:Py_ssize_t:index::
+PyUnicode_WriteChar:Py_UCS4:character::
+
+PyUnicode_READY:int:::
+PyUnicode_READY:PyObject*:o:0:
+
+PyUnicode_Substring:PyObject*::+1:
+PyUnicode_Substring:PyObject*:str:0:
+PyUnicode_Substring:Py_ssize_t:start::
+PyUnicode_Substring:Py_ssize_t:end::
+
+PyUnicode_AsUCS4:Py_UCS4*:::
+PyUnicode_AsUCS4:PyObject*:u:0:
+PyUnicode_AsUCS4:Py_UCS4*:buffer::
+PyUnicode_AsUCS4:Py_ssize_t:buflen::
+PyUnicode_AsUCS4:int:copy_null::
+
+PyUnicode_AsUCS4Copy:Py_UCS4*:::
+PyUnicode_AsUCS4Copy:PyObject*:u:0:
+
+PyUnicode_DecodeLocaleAndSize:PyObject*::+1:
+PyUnicode_DecodeLocaleAndSize:const char*:str::
+PyUnicode_DecodeLocaleAndSize:Py_ssize_t:len::
+PyUnicode_DecodeLocaleAndSize:const char*:errors::
+
+PyUnicode_DecodeLocale:PyObject*::+1:
+PyUnicode_DecodeLocale:const char*:str::
+PyUnicode_DecodeLocale:const char*:errors::
+
+PyUnicode_EncodeLocale:PyObject*::+1:
+PyUnicode_EncodeLocale:PyObject*:unicode:0:
+PyUnicode_EncodeLocale:const char*:errors::
+
+PyUnicode_FSConverter:int:::
+PyUnicode_FSConverter:PyObject*:obj:0:
+PyUnicode_FSConverter:void*:result::
+
+PyUnicode_FSDecoder:int:::
+PyUnicode_FSDecoder:PyObject*:obj:0:
+PyUnicode_FSDecoder:void*:result::
+
+PyUnicode_DecodeFSDefaultAndSize:PyObject*::+1:
+PyUnicode_DecodeFSDefaultAndSize:const char*:s::
+PyUnicode_DecodeFSDefaultAndSize:Py_ssize_t:size::
+
+PyUnicode_DecodeFSDefault:PyObject*::+1:
+PyUnicode_DecodeFSDefault:const char*:s::
+
+PyUnicode_EncodeFSDefault:PyObject*::+1:
+PyUnicode_EncodeFSDefault:PyObject*:unicode:0:
+
+PyUnicodeDecodeError_Create:PyObject*::+1:
+PyUnicodeDecodeError_Create:const char*:encoding::
+PyUnicodeDecodeError_Create:const char*:object::
+PyUnicodeDecodeError_Create:Py_ssize_t:length::
+PyUnicodeDecodeError_Create:Py_ssize_t:start::
+PyUnicodeDecodeError_Create:Py_ssize_t:end::
+PyUnicodeDecodeError_Create:const char*:reason::
+
+PyUnicodeDecodeError_GetEncoding:PyObject*::+1:
+PyUnicodeDecodeError_GetEncoding:PyObject*:exc:0:
+
+PyUnicodeDecodeError_GetEnd:Py_ssize_t:::
+PyUnicodeDecodeError_GetEnd:PyObject*:exc:0:
+PyUnicodeDecodeError_GetEnd:Py_ssize_t*:end::
+
+PyUnicodeDecodeError_GetObject:PyObject*::+1:
+PyUnicodeDecodeError_GetObject:PyObject*:exc:0:
+
+PyUnicodeDecodeError_GetReason:PyObject*::+1:
+PyUnicodeDecodeError_GetReason:PyObject*:exc:0:
+
+PyUnicodeDecodeError_GetStart:Py_ssize_t:::
+PyUnicodeDecodeError_GetStart:PyObject*:exc:0:
+PyUnicodeDecodeError_GetStart:Py_ssize_t*:start::
+
+PyUnicodeDecodeError_SetEnd:int:::
+PyUnicodeDecodeError_SetEnd:PyObject*:exc:0:
+PyUnicodeDecodeError_SetEnd:Py_ssize_t:end::
+
+PyUnicodeDecodeError_SetReason:int:::
+PyUnicodeDecodeError_SetReason:PyObject*:exc:0:
+PyUnicodeDecodeError_SetReason:const char*:reason::
+
+PyUnicodeDecodeError_SetStart:int:::
+PyUnicodeDecodeError_SetStart:PyObject*:exc:0:
+PyUnicodeDecodeError_SetStart:Py_ssize_t:start::
+
+PyUnicodeEncodeError_Create:PyObject*::+1:
+PyUnicodeEncodeError_Create:const char*:encoding::
+PyUnicodeEncodeError_Create:const Py_UNICODE*:object::
+PyUnicodeEncodeError_Create:Py_ssize_t:length::
+PyUnicodeEncodeError_Create:Py_ssize_t:start::
+PyUnicodeEncodeError_Create:Py_ssize_t:end::
+PyUnicodeEncodeError_Create:const char*:reason::
+
+PyUnicodeTranslateError_Create:PyObject*::+1:
+PyUnicodeTranslateError_Create:const Py_UNICODE*:object::
+PyUnicodeTranslateError_Create:Py_ssize_t:length::
+PyUnicodeTranslateError_Create:Py_ssize_t:start::
+PyUnicodeTranslateError_Create:Py_ssize_t:end::
+PyUnicodeTranslateError_Create:const char*:reason::
+
+PyWeakref_Check:int:::
+PyWeakref_Check:PyObject*:ob::
+
+PyWeakref_CheckProxy:int:::
+PyWeakref_CheckProxy:PyObject*:ob::
+
+PyWeakref_CheckRef:int:::
+PyWeakref_CheckRef:PyObject*:ob::
+
PyWeakref_GET_OBJECT:PyObject*::0:
PyWeakref_GET_OBJECT:PyObject*:ref:0:
@@ -1746,18 +2930,40 @@ Py_AtExit:void (*)():func::
Py_BuildValue:PyObject*::+1:
Py_BuildValue:const char*:format::
+Py_BuildValue::...::
+
+Py_VaBuildValue:PyObject*::+1:
+Py_VaBuildValue:const char*:format::
+Py_VaBuildValue:va_list:vargs::
+
+Py_CLEAR:void:::
+Py_CLEAR:PyObject*:o:-1:
Py_CompileString:PyObject*::+1:
Py_CompileString:const char*:str::
Py_CompileString:const char*:filename::
Py_CompileString:int:start::
+Py_CompileStringExFlags:PyObject*::+1:
+Py_CompileStringExFlags:const char*:str::
+Py_CompileStringExFlags:const char*:filename::
+Py_CompileStringExFlags:int:start::
+Py_CompileStringExFlags:PyCompilerFlags*:flags::
+Py_CompileStringExFlags:int:optimize::
+
Py_CompileStringFlags:PyObject*::+1:
Py_CompileStringFlags:const char*:str::
Py_CompileStringFlags:const char*:filename::
Py_CompileStringFlags:int:start::
Py_CompileStringFlags:PyCompilerFlags*:flags::
+Py_CompileStringObject:PyObject*::+1:
+Py_CompileStringObject:const char*:str::
+Py_CompileStringObject:PyObject*:filename:0:
+Py_CompileStringObject:int:start::
+Py_CompileStringObject:PyCompilerFlags*:flags::
+Py_CompileStringObject:int:optimize::
+
Py_DECREF:void:::
Py_DECREF:PyObject*:o:-1:
@@ -1776,25 +2982,25 @@ Py_FdIsInteractive:const char*:filename::
Py_Finalize:void:::
-Py_GetBuildInfoconst:const char*:::
+Py_GetBuildInfo:const char*:::
-Py_GetCompilerconst:const char*:::
+Py_GetCompiler:const char*:::
-Py_GetCopyrightconst:const char*:::
+Py_GetCopyright:const char*:::
-Py_GetExecPrefix:const char*:::
+Py_GetExecPrefix:wchar_t*:::
-Py_GetPath:const char*:::
+Py_GetPath:wchar_t*:::
-Py_GetPlatformconst:const char*:::
+Py_GetPlatform:const char*:::
-Py_GetPrefix:const char*:::
+Py_GetPrefix:wchar_t*:::
-Py_GetProgramFullPath:const char*:::
+Py_GetProgramFullPath:wchar_t*:::
-Py_GetProgramName:const char*:::
+Py_GetProgramName:wchar_t*:::
-Py_GetVersionconst:const char*:::
+Py_GetVersion:const char*:::
Py_INCREF:void:::
Py_INCREF:PyObject*:o:+1:
@@ -1805,8 +3011,14 @@ Py_IsInitialized:int:::
Py_NewInterpreter:PyThreadState*:::
+Py_ReprEnter:int:::
+Py_ReprEnter:PyObject*:object:+1:
+
+Py_ReprLeave:void:::
+Py_ReprLeave:PyObject*:object:-1:
+
Py_SetProgramName:void:::
-Py_SetProgramName:const char*:name::
+Py_SetProgramName:const wchar_t*:name::
Py_XDECREF:void:::
Py_XDECREF:PyObject*:o:-1:if o is not NULL
@@ -1814,32 +3026,24 @@ Py_XDECREF:PyObject*:o:-1:if o is not NULL
Py_XINCREF:void:::
Py_XINCREF:PyObject*:o:+1:if o is not NULL
-_PyImport_FindExtension:PyObject*::0:??? see PyImport_AddModule
-_PyImport_FindExtension:const char*:::
-_PyImport_FindExtension:const char*:::
-
_PyImport_Fini:void:::
-_PyImport_FixupExtension:PyObject*:::???
-_PyImport_FixupExtension:const char*:::
-_PyImport_FixupExtension:const char*:::
-
_PyImport_Init:void:::
_PyObject_New:PyObject*::+1:
_PyObject_New:PyTypeObject*:type:0:
-_PyObject_NewVar:PyObject*::+1:
+_PyObject_NewVar:PyVarObject*::+1:
_PyObject_NewVar:PyTypeObject*:type:0:
-_PyObject_NewVar:int:size::
+_PyObject_NewVar:Py_ssize_t:size::
-_PyString_Resize:int:::
-_PyString_Resize:PyObject**:string:+1:
-_PyString_Resize:int:newsize::
+_PyBytes_Resize:int:::
+_PyBytes_Resize:PyObject**:bytes:0:
+_PyBytes_Resize:Py_ssize_t:newsize::
_PyTuple_Resize:int:::
-_PyTuple_Resize:PyTupleObject**:p:+1:
-_PyTuple_Resize:int:new::
+_PyTuple_Resize:PyObject**:p:0:
+_PyTuple_Resize:Py_ssize_t:new::
_Py_c_diff:Py_complex:::
_Py_c_diff:Py_complex:left::
diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst
index aedbe712d3db33..5f7b3bbc4f9174 100644
--- a/Doc/distributing/index.rst
+++ b/Doc/distributing/index.rst
@@ -31,7 +31,7 @@ installing other Python projects, refer to the
Key terms
=========
-* the `Python Packaging Index `__ is a public
+* the `Python Packaging Index `__ is a public
repository of open source licensed packages made available for use by
other Python users
* the `Python Packaging Authority
@@ -40,7 +40,7 @@ Key terms
evolution of the standard packaging tools and the associated metadata and
file format standards. They maintain a variety of tools, documentation
and issue trackers on both `GitHub `__ and
- `BitBucket `__.
+ `Bitbucket `__.
* :mod:`distutils` is the original build and distribution system first added
to the Python standard library in 1998. While direct use of :mod:`distutils`
is being phased out, it still laid the foundation for the current packaging
@@ -113,11 +113,17 @@ recommended tools`_.
.. _currently recommended tools: https://packaging.python.org/guides/tool-recommendations/#packaging-tool-recommendations
-Reading the guide
-=================
+.. index::
+ single: Python Package Index (PyPI)
+ single: PyPI; (see Python Package Index (PyPI))
+
+.. _publishing-python-packages:
+
+Reading the Python Packaging User Guide
+=======================================
The Python Packaging User Guide covers the various key steps and elements
-involved in creating a project:
+involved in creating and publishing a project:
* `Project structure`_
* `Building and packaging the project`_
@@ -142,7 +148,7 @@ These are quick answers or links for some common tasks.
This isn't an easy topic, but here are a few tips:
* check the Python Packaging Index to see if the name is already in use
-* check popular hosting sites like GitHub, BitBucket, etc to see if there
+* check popular hosting sites like GitHub, Bitbucket, etc to see if there
is already a project with that name
* check what comes up in a web search for the name you're considering
* avoid particularly common words, especially ones with multiple meanings,
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index 9fce46ad266962..5ae84e04165f5a 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -78,7 +78,7 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
| | be built | :class:`distutils.core.Extension` |
+--------------------+--------------------------------+-------------------------------------------------------------+
| *classifiers* | A list of categories for the | a list of strings; valid classifiers are listed on `PyPI |
- | | package | `_. |
+ | | package | `_. |
+--------------------+--------------------------------+-------------------------------------------------------------+
| *distclass* | the :class:`Distribution` | a subclass of |
| | class to use | :class:`distutils.core.Distribution` |
@@ -183,8 +183,9 @@ the full reference.
| *sources* | list of source filenames, | a list of strings |
| | relative to the distribution | |
| | root (where the setup script | |
- | | lives), in Unix form (slash- | |
- | | separated) for portability. | |
+ | | lives), in Unix form | |
+ | | (slash-separated) for | |
+ | | portability. | |
| | Source files may be C, C++, | |
| | SWIG (.i), platform-specific | |
| | resource files, or whatever | |
@@ -940,7 +941,7 @@ timestamp dependency analysis.
.. function:: newer_group(sources, target[, missing='error'])
Return true if *target* is out-of-date with respect to any file listed in
- *sources* In other words, if *target* exists and is newer than every file in
+ *sources*. In other words, if *target* exists and is newer than every file in
*sources*, return false; otherwise return true. *missing* controls what we do
when a source file is missing; the default (``'error'``) is to blow up with an
:exc:`OSError` from inside :func:`os.stat`; if it is ``'ignore'``, we silently
@@ -1529,7 +1530,7 @@ Python's own build procedures.
=================================================
.. module:: distutils.text_file
- :synopsis: provides the TextFile class, a simple interface to text files
+ :synopsis: Provides the TextFile class, a simple interface to text files
This module provides the :class:`TextFile` class, which gives an interface to
@@ -1566,8 +1567,8 @@ lines, and joining lines with backslashes.
+------------------+--------------------------------+---------+
| option name | description | default |
+==================+================================+=========+
- | *strip_comments* | strip from ``'#'`` to end-of- | true |
- | | line, as well as any | |
+ | *strip_comments* | strip from ``'#'`` to | true |
+ | | end-of-line, as well as any | |
| | whitespace leading up to the | |
| | ``'#'``\ ---unless it is | |
| | escaped by a backslash | |
@@ -1668,7 +1669,7 @@ lines, and joining lines with backslashes.
===================================================
.. module:: distutils.version
- :synopsis: implements classes that represent module version numbers.
+ :synopsis: Implements classes that represent module version numbers.
.. % todo
@@ -1683,7 +1684,7 @@ lines, and joining lines with backslashes.
===================================================================
.. module:: distutils.cmd
- :synopsis: This module provides the abstract base class Command. This class
+ :synopsis: Provides the abstract base class :class:`~distutils.cmd.Command`. This class
is subclassed by the modules in the distutils.command subpackage.
@@ -1776,7 +1777,7 @@ Subclasses of :class:`Command` must define the following methods.
==========================================================
.. module:: distutils.command
- :synopsis: This subpackage contains one module for each standard Distutils command.
+ :synopsis: Contains one module for each standard Distutils command.
.. % \subsubsection{Individual Distutils commands}
@@ -2020,7 +2021,7 @@ This is described in more detail in :pep:`301`.
===================================================================
.. module:: distutils.command.check
- :synopsis: Check the metadata of a package
+ :synopsis: Check the meta-data of a package
The ``check`` command performs some tests on the meta-data of a package.
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index f523a672340876..0a83f8bd659984 100644
--- a/Doc/distutils/builtdist.rst
+++ b/Doc/distutils/builtdist.rst
@@ -21,7 +21,7 @@ specialty---writing code and creating source distributions---while an
intermediary species called *packagers* springs up to turn source distributions
into built distributions for as many platforms as there are packagers.
-Of course, the module developer could be his own packager; or the packager could
+Of course, the module developer could be their own packager; or the packager could
be a volunteer "out there" somewhere who has access to a platform which the
original developer does not; or it could be software periodically grabbing new
source distributions and turning them into built distributions for as many
@@ -63,9 +63,9 @@ distribution to generate: for example, ::
python setup.py bdist --format=zip
-would, when run on a Unix system, create :file:`Distutils-1.0.{plat}.zip`\
----again, this archive would be unpacked from the root directory to install the
-Distutils.
+would, when run on a Unix system, create
+:file:`Distutils-1.0.{plat}.zip`\ ---again, this archive would be unpacked
+from the root directory to install the Distutils.
The available formats for built distributions are:
@@ -313,8 +313,8 @@ or the :command:`bdist` command with the :option:`!--formats` option::
If you have a pure module distribution (only containing pure Python modules and
packages), the resulting installer will be version independent and have a name
-like :file:`foo-1.0.win32.exe`. These installers can even be created on Unix
-platforms or Mac OS X.
+like :file:`foo-1.0.win32.exe`. Note that creating ``wininst`` binary
+distributions in only supported on Windows systems.
If you have a non-pure distribution, the extensions can only be created on a
Windows platform, and will be Python version dependent. The installer filename
diff --git a/Doc/distutils/configfile.rst b/Doc/distutils/configfile.rst
index 21f1acdace5f19..0874d05fe703a1 100644
--- a/Doc/distutils/configfile.rst
+++ b/Doc/distutils/configfile.rst
@@ -13,8 +13,8 @@ edit is a cheap and easy way to solicit it. Configuration files also let you
provide default values for any command option, which the installer can then
override either on the command-line or by editing the config file.
-The setup configuration file is a useful middle-ground between the setup script
----which, ideally, would be opaque to installers [#]_---and the command-line to
+The setup configuration file is a useful middle-ground between the setup
+script---which, ideally, would be opaque to installers [#]_---and the command-line to
the setup script, which is outside of your control and entirely up to the
installer. In fact, :file:`setup.cfg` (and any other Distutils configuration
files present on the target system) are processed after the contents of the
@@ -36,7 +36,9 @@ consequences:
* installers can override anything in :file:`setup.cfg` using the command-line
options to :file:`setup.py`
-The basic syntax of the configuration file is simple::
+The basic syntax of the configuration file is simple:
+
+.. code-block:: ini
[command]
option=value
@@ -51,9 +53,11 @@ option values can be split across multiple lines simply by indenting the
continuation lines.
You can find out the list of options supported by a particular command with the
-universal :option:`!--help` option, e.g. ::
+universal :option:`!--help` option, e.g.
+
+.. code-block:: shell-session
- > python setup.py --help build_ext
+ $ python setup.py --help build_ext
[...]
Options for 'build_ext' command:
--build-lib (-b) directory for compiled extension modules
@@ -75,14 +79,18 @@ For example, say you want your extensions to be built "in-place"---that is, you
have an extension :mod:`pkg.ext`, and you want the compiled extension file
(:file:`ext.so` on Unix, say) to be put in the same source directory as your
pure Python modules :mod:`pkg.mod1` and :mod:`pkg.mod2`. You can always use the
-:option:`!--inplace` option on the command-line to ensure this::
+:option:`!--inplace` option on the command-line to ensure this:
+
+.. code-block:: sh
python setup.py build_ext --inplace
But this requires that you always specify the :command:`build_ext` command
explicitly, and remember to provide :option:`!--inplace`. An easier way is to
"set and forget" this option, by encoding it in :file:`setup.cfg`, the
-configuration file for this distribution::
+configuration file for this distribution:
+
+.. code-block:: ini
[build_ext]
inplace=1
@@ -103,7 +111,9 @@ information comes from the setup script, and some is automatically generated by
the Distutils (such as the list of files installed). But some of it has to be
supplied as options to :command:`bdist_rpm`, which would be very tedious to do
on the command-line for every run. Hence, here is a snippet from the Distutils'
-own :file:`setup.cfg`::
+own :file:`setup.cfg`:
+
+.. code-block:: ini
[bdist_rpm]
release = 1
diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst
index d6f7640fcb6826..aaf4536dfa5431 100644
--- a/Doc/distutils/index.rst
+++ b/Doc/distutils/index.rst
@@ -34,7 +34,6 @@ very little overhead for build/release/install mechanics.
configfile.rst
sourcedist.rst
builtdist.rst
- packageindex.rst
examples.rst
extending.rst
commandref.rst
diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst
index 8f46bd74c5b01a..7721484fe73717 100644
--- a/Doc/distutils/introduction.rst
+++ b/Doc/distutils/introduction.rst
@@ -94,7 +94,7 @@ containing your setup script :file:`setup.py`, and your module :file:`foo.py`.
The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and
will unpack into a directory :file:`foo-1.0`.
-If an end-user wishes to install your :mod:`foo` module, all she has to do is
+If an end-user wishes to install your :mod:`foo` module, all they have to do is
download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the
:file:`foo-1.0` directory---run ::
@@ -193,8 +193,8 @@ modules using the Distutils:
module distribution
a collection of Python modules distributed together as a single downloadable
resource and meant to be installed *en masse*. Examples of some well-known
- module distributions are NumPy, SciPy, PIL (the Python Imaging
- Library), or mxBase. (This would be called a *package*, except that term is
+ module distributions are NumPy, SciPy, Pillow,
+ or mxBase. (This would be called a *package*, except that term is
already taken in the Python context: a single module distribution may contain
zero, one, or many Python packages.)
diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst
index 44556e3df9c5b1..ccb9a598b2b7a2 100644
--- a/Doc/distutils/packageindex.rst
+++ b/Doc/distutils/packageindex.rst
@@ -1,6 +1,4 @@
-.. index::
- single: Python Package Index (PyPI)
- single: PyPI; (see Python Package Index (PyPI))
+:orphan:
.. _package-index:
@@ -8,242 +6,11 @@
The Python Package Index (PyPI)
*******************************
-The `Python Package Index (PyPI)`_ stores :ref:`meta-data `
-describing distributions packaged with distutils, as well as package data like
-distribution files if a package author wishes.
+The `Python Package Index (PyPI)`_ stores metadata describing distributions
+packaged with distutils and other publishing tools, as well the distribution
+archives themselves.
-Distutils provides the :command:`register` and :command:`upload` commands for
-pushing meta-data and distribution files to PyPI, respectively. See
-:ref:`package-commands` for information on these commands.
+References to up to date PyPI documentation can be found at
+:ref:`publishing-python-packages`.
-
-PyPI overview
-=============
-
-PyPI lets you submit any number of versions of your distribution to the index.
-If you alter the meta-data for a particular version, you can submit it again
-and the index will be updated.
-
-PyPI holds a record for each (name, version) combination submitted. The first
-user to submit information for a given name is designated the Owner of that
-name. Changes can be submitted through the :command:`register` command or
-through the web interface. Owners can designate other users as Owners or
-Maintainers. Maintainers can edit the package information, but not designate
-new Owners or Maintainers.
-
-By default PyPI displays only the newest version of a given package. The web
-interface lets one change this default behavior and manually select which
-versions to display and hide.
-
-For each version, PyPI displays a home page. The home page is created from
-the ``long_description`` which can be submitted via the :command:`register`
-command. See :ref:`package-display` for more information.
-
-
-.. _package-commands:
-
-Distutils commands
-==================
-
-Distutils exposes two commands for submitting package data to PyPI: the
-:ref:`register ` command for submitting meta-data to PyPI
-and the :ref:`upload ` command for submitting distribution
-files. Both commands read configuration data from a special file called a
-:ref:`.pypirc file `.
-
-
-.. _package-register:
-
-The ``register`` command
-------------------------
-
-The distutils command :command:`register` is used to submit your distribution's
-meta-data to an index server. It is invoked as follows::
-
- python setup.py register
-
-Distutils will respond with the following prompt::
-
- running register
- We need to know who you are, so please choose either:
- 1. use your existing login,
- 2. register as a new user,
- 3. have the server generate a new password for you (and email it to you), or
- 4. quit
- Your selection [default 1]:
-
-Note: if your username and password are saved locally, you will not see this
-menu. Also, refer to :ref:`pypirc` for how to store your credentials in a
-:file:`.pypirc` file.
-
-If you have not registered with PyPI, then you will need to do so now. You
-should choose option 2, and enter your details as required. Soon after
-submitting your details, you will receive an email which will be used to confirm
-your registration.
-
-Once you are registered, you may choose option 1 from the menu. You will be
-prompted for your PyPI username and password, and :command:`register` will then
-submit your meta-data to the index.
-
-See :ref:`package-cmdoptions` for options to the :command:`register` command.
-
-
-.. _package-upload:
-
-The ``upload`` command
-----------------------
-
-The distutils command :command:`upload` pushes the distribution files to PyPI.
-
-The command is invoked immediately after building one or more distribution
-files. For example, the command ::
-
- python setup.py sdist bdist_wininst upload
-
-will cause the source distribution and the Windows installer to be uploaded to
-PyPI. Note that these will be uploaded even if they are built using an earlier
-invocation of :file:`setup.py`, but that only distributions named on the command
-line for the invocation including the :command:`upload` command are uploaded.
-
-If a :command:`register` command was previously called in the same command,
-and if the password was entered in the prompt, :command:`upload` will reuse the
-entered password. This is useful if you do not want to store a password in
-clear text in a :file:`.pypirc` file.
-
-You can use the ``--sign`` option to tell :command:`upload` to sign each
-uploaded file using GPG (GNU Privacy Guard). The :program:`gpg` program must
-be available for execution on the system :envvar:`PATH`. You can also specify
-which key to use for signing using the ``--identity=name`` option.
-
-See :ref:`package-cmdoptions` for additional options to the :command:`upload`
-command.
-
-
-.. _package-cmdoptions:
-
-Additional command options
---------------------------
-
-This section describes options common to both the :command:`register` and
-:command:`upload` commands.
-
-The ``--repository`` or ``-r`` option lets you specify a PyPI server
-different from the default. For example::
-
- python setup.py sdist bdist_wininst upload -r https://example.com/pypi
-
-For convenience, a name can be used in place of the URL when the
-:file:`.pypirc` file is configured to do so. For example::
-
- python setup.py register -r other
-
-See :ref:`pypirc` for more information on defining alternate servers.
-
-The ``--show-response`` option displays the full response text from the PyPI
-server, which is useful when debugging problems with registering and uploading.
-
-
-.. index::
- single: .pypirc file
- single: Python Package Index (PyPI); .pypirc file
-
-.. _pypirc:
-
-The ``.pypirc`` file
---------------------
-
-The :command:`register` and :command:`upload` commands both check for the
-existence of a :file:`.pypirc` file at the location :file:`$HOME/.pypirc`.
-If this file exists, the command uses the username, password, and repository
-URL configured in the file. The format of a :file:`.pypirc` file is as
-follows::
-
- [distutils]
- index-servers =
- pypi
-
- [pypi]
- repository:
- username:
- password:
-
-The *distutils* section defines an *index-servers* variable that lists the
-name of all sections describing a repository.
-
-Each section describing a repository defines three variables:
-
-- *repository*, that defines the url of the PyPI server. Defaults to
- ``https://upload.pypi.org/legacy/``.
-- *username*, which is the registered username on the PyPI server.
-- *password*, that will be used to authenticate. If omitted the user
- will be prompt to type it when needed.
-
-If you want to define another server a new section can be created and
-listed in the *index-servers* variable::
-
- [distutils]
- index-servers =
- pypi
- other
-
- [pypi]
- repository:
- username:
- password:
-
- [other]
- repository: https://example.com/pypi
- username:
- password:
-
-This allows the :command:`register` and :command:`upload` commands to be
-called with the ``--repository`` option as described in
-:ref:`package-cmdoptions`.
-
-Specifically, you might want to add the `PyPI Test Repository
-`_ to your ``.pypirc`` to facilitate
-testing before doing your first upload to ``PyPI`` itself.
-
-
-.. _package-display:
-
-PyPI package display
-====================
-
-The ``long_description`` field plays a special role at PyPI. It is used by
-the server to display a home page for the registered package.
-
-If you use the `reStructuredText `_
-syntax for this field, PyPI will parse it and display an HTML output for
-the package home page.
-
-The ``long_description`` field can be attached to a text file located
-in the package::
-
- from distutils.core import setup
-
- with open('README.txt') as file:
- long_description = file.read()
-
- setup(name='Distutils',
- long_description=long_description)
-
-In that case, :file:`README.txt` is a regular reStructuredText text file located
-in the root of the package besides :file:`setup.py`.
-
-To prevent registering broken reStructuredText content, you can use the
-:program:`rst2html` program that is provided by the :mod:`docutils` package and
-check the ``long_description`` from the command line:
-
-.. code-block:: shell-session
-
- $ python setup.py --long-description | rst2html.py > output.html
-
-:mod:`docutils` will display a warning if there's something wrong with your
-syntax. Because PyPI applies additional checks (e.g. by passing ``--no-raw``
-to ``rst2html.py`` in the command above), being able to run the command above
-without warnings does not guarantee that PyPI will convert the content
-successfully.
-
-
-.. _Python Package Index (PyPI): https://pypi.python.org/pypi
+.. _Python Package Index (PyPI): https://pypi.org
diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst
index 952607a4073b25..1f99f62f6affef 100644
--- a/Doc/distutils/setupscript.rst
+++ b/Doc/distutils/setupscript.rst
@@ -523,21 +523,24 @@ following way::
setup(...,
data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
- ('config', ['cfg/data.cfg']),
- ('/etc/init.d', ['init-script'])]
+ ('config', ['cfg/data.cfg'])],
)
-Note that you can specify the directory names where the data files will be
-installed, but you cannot rename the data files themselves.
-
Each (*directory*, *files*) pair in the sequence specifies the installation
-directory and the files to install there. If *directory* is a relative path, it
-is interpreted relative to the installation prefix (Python's ``sys.prefix`` for
-pure-Python packages, ``sys.exec_prefix`` for packages that contain extension
-modules). Each file name in *files* is interpreted relative to the
-:file:`setup.py` script at the top of the package source distribution. No
-directory information from *files* is used to determine the final location of
-the installed file; only the name of the file is used.
+directory and the files to install there.
+
+Each file name in *files* is interpreted relative to the :file:`setup.py`
+script at the top of the package source distribution. Note that you can
+specify the directory where the data files will be installed, but you cannot
+rename the data files themselves.
+
+The *directory* should be a relative path. It is interpreted relative to the
+installation prefix (Python's ``sys.prefix`` for system installations;
+``site.USER_BASE`` for user installations). Distutils allows *directory* to be
+an absolute installation path, but this is discouraged since it is
+incompatible with the wheel packaging format. No directory information from
+*files* is used to determine the final location of the installed file; only
+the name of the file is used.
You can specify the ``data_files`` options as a simple sequence of files
without specifying a target directory, but this is not recommended, and the
@@ -609,9 +612,8 @@ Notes:
provided, distutils lists it as the author in :file:`PKG-INFO`.
(4)
- The ``long_description`` field is used by PyPI when you are
- :ref:`registering ` a package, to
- :ref:`build its home page `.
+ The ``long_description`` field is used by PyPI when you publish a package,
+ to build its project page.
(5)
The ``license`` field is a text indicating the license covering the
@@ -625,7 +627,7 @@ Notes:
(7)
The valid classifiers are listed on
- `PyPI `_.
+ `PyPI `_.
(8)
To preserve backward compatibility, this field also accepts a string. If
@@ -682,9 +684,8 @@ information is sometimes used to indicate sub-releases. These are
)
.. versionchanged:: 3.7
- :class:`~distutils.core.setup` now raises a :exc:`TypeError` if
- ``classifiers``, ``keywords`` and ``platforms`` fields are not specified
- as a list.
+ :class:`~distutils.core.setup` now warns when ``classifiers``, ``keywords``
+ or ``platforms`` fields are not specified as a list or a string.
.. _debug-setup-script:
diff --git a/Doc/distutils/uploading.rst b/Doc/distutils/uploading.rst
index 4bce6997f9f83a..4c391cab072ea6 100644
--- a/Doc/distutils/uploading.rst
+++ b/Doc/distutils/uploading.rst
@@ -4,4 +4,5 @@
Uploading Packages to the Package Index
***************************************
-The contents of this page have moved to the section :ref:`package-index`.
+References to up to date PyPI documentation can be found at
+:ref:`publishing-python-packages`.
diff --git a/Doc/docutils.conf b/Doc/docutils.conf
deleted file mode 100644
index bda4f5dc2351dc..00000000000000
--- a/Doc/docutils.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[restructuredtext parser]
-smartquotes-locales: ja: ""''
diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst
index ab2f61614afc4e..881390da0e2759 100644
--- a/Doc/extending/embedding.rst
+++ b/Doc/extending/embedding.rst
@@ -53,6 +53,7 @@ interface. This interface is intended to execute a Python script without needing
to interact with the application directly. This can for example be used to
perform some operation on a file. ::
+ #define PY_SSIZE_T_CLEAN
#include
int
@@ -195,7 +196,7 @@ function is then made with::
pValue = PyObject_CallObject(pFunc, pArgs);
-Upon return of the function, ``pValue`` is either *NULL* or it contains a
+Upon return of the function, ``pValue`` is either ``NULL`` or it contains a
reference to the return value of the function. Be sure to release the reference
after examining the value.
@@ -323,7 +324,7 @@ options. In this case, the :mod:`sysconfig` module is a useful tool to
programmatically extract the configuration values that you will want to
combine together. For example:
-.. code-block:: python
+.. code-block:: pycon
>>> import sysconfig
>>> sysconfig.get_config_var('LIBS')
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index e02f7837b69ed2..fb15ecf39b7cd6 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -43,7 +43,9 @@ Let's create an extension module called ``spam`` (the favorite food of Monty
Python fans...) and let's say we want to create a Python interface to the C
library function :c:func:`system` [#]_. This function takes a null-terminated
character string as argument and returns an integer. We want this function to
-be callable from Python as follows::
+be callable from Python as follows:
+
+.. code-block:: pycon
>>> import spam
>>> status = spam.system("ls -l")
@@ -53,8 +55,9 @@ called ``spam``, the C file containing its implementation is called
:file:`spammodule.c`; if the module name is very long, like ``spammify``, the
module name can be just :file:`spammify.c`.)
-The first line of our file can be::
+The first two lines of our file can be::
+ #define PY_SSIZE_T_CLEAN
#include
which pulls in the Python API (you can add a comment describing the purpose of
@@ -66,6 +69,9 @@ the module and a copyright notice if you like).
headers on some systems, you *must* include :file:`Python.h` before any standard
headers are included.
+ It is recommended to always define ``PY_SSIZE_T_CLEAN`` before including
+ ``Python.h``. See :ref:`parsetuple` for a description of this macro.
+
All user-visible symbols defined by :file:`Python.h` have a prefix of ``Py`` or
``PY``, except those defined in standard header files. For convenience, and
since they are used extensively by the Python interpreter, ``"Python.h"``
@@ -111,7 +117,7 @@ store the converted values. More about this later.
type and its components have been stored in the variables whose addresses are
passed. It returns false (zero) if an invalid argument list was passed. In the
latter case it also raises an appropriate exception so the calling function can
-return *NULL* immediately (as we saw in the example).
+return ``NULL`` immediately (as we saw in the example).
.. _extending-errors:
@@ -121,8 +127,8 @@ Intermezzo: Errors and Exceptions
An important convention throughout the Python interpreter is the following: when
a function fails, it should set an exception condition and return an error value
-(usually a *NULL* pointer). Exceptions are stored in a static global variable
-inside the interpreter; if this variable is *NULL* no exception has occurred. A
+(usually a ``NULL`` pointer). Exceptions are stored in a static global variable
+inside the interpreter; if this variable is ``NULL`` no exception has occurred. A
second global variable stores the "associated value" of the exception (the
second argument to :keyword:`raise`). A third variable contains the stack
traceback in case the error originated in Python code. These three variables
@@ -146,13 +152,13 @@ its associated value. You don't need to :c:func:`Py_INCREF` the objects passed
to any of these functions.
You can test non-destructively whether an exception has been set with
-:c:func:`PyErr_Occurred`. This returns the current exception object, or *NULL*
+:c:func:`PyErr_Occurred`. This returns the current exception object, or ``NULL``
if no exception has occurred. You normally don't need to call
:c:func:`PyErr_Occurred` to see whether an error occurred in a function call,
since you should be able to tell from the return value.
When a function *f* that calls another function *g* detects that the latter
-fails, *f* should itself return an error value (usually *NULL* or ``-1``). It
+fails, *f* should itself return an error value (usually ``NULL`` or ``-1``). It
should *not* call one of the :c:func:`PyErr_\*` functions --- one has already
been called by *g*. *f*'s caller is then supposed to also return an error
indication to *its* caller, again *without* calling :c:func:`PyErr_\*`, and so on
@@ -203,7 +209,7 @@ usually declare a static object variable at the beginning of your file::
static PyObject *SpamError;
and initialize it in your module's initialization function (:c:func:`PyInit_spam`)
-with an exception object (leaving out the error checking for now)::
+with an exception object::
PyMODINIT_FUNC
PyInit_spam(void)
@@ -215,14 +221,20 @@ with an exception object (leaving out the error checking for now)::
return NULL;
SpamError = PyErr_NewException("spam.error", NULL, NULL);
- Py_INCREF(SpamError);
- PyModule_AddObject(m, "error", SpamError);
+ Py_XINCREF(SpamError);
+ if (PyModule_AddObject(m, "error", SpamError) < 0) {
+ Py_XDECREF(SpamError);
+ Py_CLEAR(SpamError);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
Note that the Python name for the exception object is :exc:`spam.error`. The
:c:func:`PyErr_NewException` function may create a class with the base class
-being :exc:`Exception` (unless another class is passed in instead of *NULL*),
+being :exc:`Exception` (unless another class is passed in instead of ``NULL``),
described in :ref:`bltin-exceptions`.
Note also that the :c:data:`SpamError` variable retains a reference to the newly
@@ -266,7 +278,7 @@ statement::
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
-It returns *NULL* (the error indicator for functions returning object pointers)
+It returns ``NULL`` (the error indicator for functions returning object pointers)
if an error is detected in the argument list, relying on the exception set by
:c:func:`PyArg_ParseTuple`. Otherwise the string value of the argument has been
copied to the local variable :c:data:`command`. This is a pointer assignment and
@@ -296,7 +308,7 @@ macro)::
return Py_None;
:c:data:`Py_None` is the C name for the special Python object ``None``. It is a
-genuine Python object rather than a *NULL* pointer, which means "error" in most
+genuine Python object rather than a ``NULL`` pointer, which means "error" in most
contexts, as we have seen.
@@ -364,7 +376,7 @@ inserts built-in function objects into the newly created module based upon the
table (an array of :c:type:`PyMethodDef` structures) found in the module definition.
:c:func:`PyModule_Create` returns a pointer to the module object
that it creates. It may abort with a fatal error for
-certain errors, or return *NULL* if the module could not be initialized
+certain errors, or return ``NULL`` if the module could not be initialized
satisfactorily. The init function must return the module object to its caller,
so that it then gets inserted into ``sys.modules``.
@@ -439,7 +451,9 @@ part of the Python interpreter, you will have to change the configuration setup
and rebuild the interpreter. Luckily, this is very simple on Unix: just place
your file (:file:`spammodule.c` for example) in the :file:`Modules/` directory
of an unpacked source distribution, add a line to the file
-:file:`Modules/Setup.local` describing your file::
+:file:`Modules/Setup.local` describing your file:
+
+.. code-block:: sh
spam spammodule.o
@@ -450,7 +464,9 @@ subdirectory, but then you must first rebuild :file:`Makefile` there by running
:file:`Setup` file.)
If your module requires additional libraries to link with, these can be listed
-on the line in the configuration file as well, for instance::
+on the line in the configuration file as well, for instance:
+
+.. code-block:: sh
spam spammodule.o -lX11
@@ -510,8 +526,8 @@ This function must be registered with the interpreter using the
:ref:`parsetuple`.
The macros :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF` increment/decrement the
-reference count of an object and are safe in the presence of *NULL* pointers
-(but note that *temp* will not be *NULL* in this context). More info on them
+reference count of an object and are safe in the presence of ``NULL`` pointers
+(but note that *temp* will not be ``NULL`` in this context). More info on them
in section :ref:`refcounts`.
.. index:: single: PyObject_CallObject()
@@ -520,7 +536,7 @@ Later, when it is time to call the function, you call the C function
:c:func:`PyObject_CallObject`. This function has two arguments, both pointers to
arbitrary Python objects: the Python function, and the argument list. The
argument list must always be a tuple object, whose length is the number of
-arguments. To call the Python function with no arguments, pass in NULL, or
+arguments. To call the Python function with no arguments, pass in ``NULL``, or
an empty tuple; to call it with one argument, pass a singleton tuple.
:c:func:`Py_BuildValue` returns a tuple when its format string consists of zero
or more format codes between parentheses. For example::
@@ -539,8 +555,9 @@ or more format codes between parentheses. For example::
:c:func:`PyObject_CallObject` returns a Python object pointer: this is the return
value of the Python function. :c:func:`PyObject_CallObject` is
"reference-count-neutral" with respect to its arguments. In the example a new
-tuple was created to serve as the argument list, which is :c:func:`Py_DECREF`\
--ed immediately after the :c:func:`PyObject_CallObject` call.
+tuple was created to serve as the argument list, which is
+:c:func:`Py_DECREF`\ -ed immediately after the :c:func:`PyObject_CallObject`
+call.
The return value of :c:func:`PyObject_CallObject` is "new": either it is a brand
new object, or it is an existing object whose reference count has been
@@ -549,7 +566,7 @@ somehow :c:func:`Py_DECREF` the result, even (especially!) if you are not
interested in its value.
Before you do this, however, it is important to check that the return value
-isn't *NULL*. If it is, the Python function terminated by raising an exception.
+isn't ``NULL``. If it is, the Python function terminated by raising an exception.
If the C code that called :c:func:`PyObject_CallObject` is called from Python, it
should now return an error indication to its Python caller, so the interpreter
can print a stack trace, or the calling Python code can handle the exception.
@@ -706,7 +723,7 @@ The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows::
The *arg* and *format* parameters are identical to those of the
:c:func:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of
keywords received as the third parameter from the Python runtime. The *kwlist*
-parameter is a *NULL*-terminated list of strings which identify the parameters;
+parameter is a ``NULL``-terminated list of strings which identify the parameters;
the names are matched with the type information from *format* from left to
right. On success, :c:func:`PyArg_ParseTupleAndKeywords` returns true, otherwise
it returns false and raises an appropriate exception.
@@ -722,7 +739,8 @@ it returns false and raises an appropriate exception.
Here is an example module which uses keywords, based on an example by Geoff
Philbrick (philbrick@hks.com)::
- #include "Python.h"
+ #define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */
+ #include
static PyObject *
keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)
@@ -1066,32 +1084,32 @@ NULL Pointers
-------------
In general, functions that take object references as arguments do not expect you
-to pass them *NULL* pointers, and will dump core (or cause later core dumps) if
-you do so. Functions that return object references generally return *NULL* only
-to indicate that an exception occurred. The reason for not testing for *NULL*
+to pass them ``NULL`` pointers, and will dump core (or cause later core dumps) if
+you do so. Functions that return object references generally return ``NULL`` only
+to indicate that an exception occurred. The reason for not testing for ``NULL``
arguments is that functions often pass the objects they receive on to other
-function --- if each function were to test for *NULL*, there would be a lot of
+function --- if each function were to test for ``NULL``, there would be a lot of
redundant tests and the code would run more slowly.
-It is better to test for *NULL* only at the "source:" when a pointer that may be
-*NULL* is received, for example, from :c:func:`malloc` or from a function that
+It is better to test for ``NULL`` only at the "source:" when a pointer that may be
+``NULL`` is received, for example, from :c:func:`malloc` or from a function that
may raise an exception.
-The macros :c:func:`Py_INCREF` and :c:func:`Py_DECREF` do not check for *NULL*
+The macros :c:func:`Py_INCREF` and :c:func:`Py_DECREF` do not check for ``NULL``
pointers --- however, their variants :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF`
do.
The macros for checking for a particular object type (``Pytype_Check()``) don't
-check for *NULL* pointers --- again, there is much code that calls several of
+check for ``NULL`` pointers --- again, there is much code that calls several of
these in a row to test an object against various different expected types, and
-this would generate redundant tests. There are no variants with *NULL*
+this would generate redundant tests. There are no variants with ``NULL``
checking.
The C function calling mechanism guarantees that the argument list passed to C
-functions (``args`` in the examples) is never *NULL* --- in fact it guarantees
+functions (``args`` in the examples) is never ``NULL`` --- in fact it guarantees
that it is always a tuple [#]_.
-It is a severe error to ever let a *NULL* pointer "escape" to the Python user.
+It is a severe error to ever let a ``NULL`` pointer "escape" to the Python user.
.. Frank Stajano:
A pedagogically buggy example, along the lines of the previous listing, would
@@ -1166,7 +1184,7 @@ different ways between the module providing the code and the client modules.
Whichever method you choose, it's important to name your Capsules properly.
The function :c:func:`PyCapsule_New` takes a name parameter
-(:c:type:`const char \*`); you're permitted to pass in a *NULL* name, but
+(:c:type:`const char \*`); you're permitted to pass in a ``NULL`` name, but
we strongly encourage you to specify a name. Properly named Capsules provide
a degree of runtime type-safety; there is no feasible way to tell one unnamed
Capsule from another.
@@ -1221,7 +1239,7 @@ The function :c:func:`spam_system` is modified in a trivial way::
In the beginning of the module, right after the line ::
- #include "Python.h"
+ #include
two more lines must be added::
@@ -1249,8 +1267,12 @@ function must take care of initializing the C API pointer array::
/* Create a Capsule containing the API pointer array's address */
c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL);
- if (c_api_object != NULL)
- PyModule_AddObject(m, "_C_API", c_api_object);
+ if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) {
+ Py_XDECREF(c_api_object);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst
index 80594e357fd497..0994e3e8627dfa 100644
--- a/Doc/extending/index.rst
+++ b/Doc/extending/index.rst
@@ -26,9 +26,11 @@ Recommended third party tools
=============================
This guide only covers the basic tools for creating extensions provided
-as part of this version of CPython. Third party tools like Cython,
-``cffi``, SWIG and Numba offer both simpler and more sophisticated
-approaches to creating C and C++ extensions for Python.
+as part of this version of CPython. Third party tools like
+`Cython `_, `cffi `_,
+`SWIG `_ and `Numba `_
+offer both simpler and more sophisticated approaches to creating C and C++
+extensions for Python.
.. seealso::
@@ -52,6 +54,7 @@ C extensions.
:numbered:
extending.rst
+ newtypes_tutorial.rst
newtypes.rst
building.rst
windows.rst
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index 62fbdb87a53000..315300e192576c 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -1,889 +1,11 @@
.. highlightlang:: c
-
-.. _defining-new-types:
-
-******************
-Defining New Types
-******************
-
-.. sectionauthor:: Michael Hudson
-.. sectionauthor:: Dave Kuhlman
-.. sectionauthor:: Jim Fulton
-
-
-As mentioned in the last chapter, Python allows the writer of an extension
-module to define new types that can be manipulated from Python code, much like
-strings and lists in core Python.
-
-This is not hard; the code for all extension types follows a pattern, but there
-are some details that you need to understand before you can get started.
-
-
-.. _dnt-basics:
-
-The Basics
-==========
-
-The Python runtime sees all Python objects as variables of type
-:c:type:`PyObject\*`, which serves as a "base type" for all Python objects.
-:c:type:`PyObject` itself only contains the refcount and a pointer to the
-object's "type object". This is where the action is; the type object determines
-which (C) functions get called when, for instance, an attribute gets looked
-up on an object or it is multiplied by another object. These C functions
-are called "type methods".
-
-So, if you want to define a new object type, you need to create a new type
-object.
-
-This sort of thing can only be explained by example, so here's a minimal, but
-complete, module that defines a new type:
-
-.. literalinclude:: ../includes/noddy.c
-
-
-Now that's quite a bit to take in at once, but hopefully bits will seem familiar
-from the last chapter.
-
-The first bit that will be new is::
-
- typedef struct {
- PyObject_HEAD
- } noddy_NoddyObject;
-
-This is what a Noddy object will contain---in this case, nothing more than what
-every Python object contains---a field called ``ob_base`` of type
-:c:type:`PyObject`. :c:type:`PyObject` in turn, contains an ``ob_refcnt``
-field and a pointer to a type object. These can be accessed using the macros
-:c:macro:`Py_REFCNT` and :c:macro:`Py_TYPE` respectively. These are the fields
-the :c:macro:`PyObject_HEAD` macro brings in. The reason for the macro is to
-standardize the layout and to enable special debugging fields in debug builds.
-
-Note that there is no semicolon after the :c:macro:`PyObject_HEAD` macro;
-one is included in the macro definition. Be wary of adding one by
-accident; it's easy to do from habit, and your compiler might not complain,
-but someone else's probably will! (On Windows, MSVC is known to call this an
-error and refuse to compile the code.)
-
-For contrast, let's take a look at the corresponding definition for standard
-Python floats::
-
- typedef struct {
- PyObject_HEAD
- double ob_fval;
- } PyFloatObject;
-
-Moving on, we come to the crunch --- the type object. ::
-
- static PyTypeObject noddy_NoddyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "noddy.Noddy", /* tp_name */
- sizeof(noddy_NoddyObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_as_async */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- "Noddy objects", /* tp_doc */
- };
-
-Now if you go and look up the definition of :c:type:`PyTypeObject` in
-:file:`object.h` you'll see that it has many more fields that the definition
-above. The remaining fields will be filled with zeros by the C compiler, and
-it's common practice to not specify them explicitly unless you need them.
-
-This is so important that we're going to pick the top of it apart still
-further::
-
- PyVarObject_HEAD_INIT(NULL, 0)
-
-This line is a bit of a wart; what we'd like to write is::
-
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
-
-as the type of a type object is "type", but this isn't strictly conforming C and
-some compilers complain. Fortunately, this member will be filled in for us by
-:c:func:`PyType_Ready`. ::
-
- "noddy.Noddy", /* tp_name */
-
-The name of our type. This will appear in the default textual representation of
-our objects and in some error messages, for example::
-
- >>> "" + noddy.new_noddy()
- Traceback (most recent call last):
- File "", line 1, in
- TypeError: cannot add type "noddy.Noddy" to string
-
-Note that the name is a dotted name that includes both the module name and the
-name of the type within the module. The module in this case is :mod:`noddy` and
-the type is :class:`Noddy`, so we set the type name to :class:`noddy.Noddy`.
-One side effect of using an undotted name is that the pydoc documentation tool
-will not list the new type in the module documentation. ::
-
- sizeof(noddy_NoddyObject), /* tp_basicsize */
-
-This is so that Python knows how much memory to allocate when you call
-:c:func:`PyObject_New`.
-
-.. note::
-
- If you want your type to be subclassable from Python, and your type has the same
- :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have problems with multiple
- inheritance. A Python subclass of your type will have to list your type first
- in its :attr:`~class.__bases__`, or else it will not be able to call your type's
- :meth:`__new__` method without getting an error. You can avoid this problem by
- ensuring that your type has a larger value for :c:member:`~PyTypeObject.tp_basicsize` than its
- base type does. Most of the time, this will be true anyway, because either your
- base type will be :class:`object`, or else you will be adding data members to
- your base type, and therefore increasing its size.
-
-::
-
- 0, /* tp_itemsize */
-
-This has to do with variable length objects like lists and strings. Ignore this
-for now.
-
-Skipping a number of type methods that we don't provide, we set the class flags
-to :const:`Py_TPFLAGS_DEFAULT`. ::
-
- Py_TPFLAGS_DEFAULT, /* tp_flags */
-
-All types should include this constant in their flags. It enables all of the
-members defined until at least Python 3.3. If you need further members,
-you will need to OR the corresponding flags.
-
-We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::
-
- "Noddy objects", /* tp_doc */
-
-Now we get into the type methods, the things that make your objects different
-from the others. We aren't going to implement any of these in this version of
-the module. We'll expand this example later to have more interesting behavior.
-
-For now, all we want to be able to do is to create new :class:`Noddy` objects.
-To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new` implementation.
-In this case, we can just use the default implementation provided by the API
-function :c:func:`PyType_GenericNew`. ::
-
- PyType_GenericNew, /* tp_new */
-
-All the other type methods are *NULL*, so we'll go over them later --- that's
-for a later section!
-
-Everything else in the file should be familiar, except for some code in
-:c:func:`PyInit_noddy`::
-
- if (PyType_Ready(&noddy_NoddyType) < 0)
- return;
-
-This initializes the :class:`Noddy` type, filing in a number of members,
-including :attr:`ob_type` that we initially set to *NULL*. ::
-
- PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
-
-This adds the type to the module dictionary. This allows us to create
-:class:`Noddy` instances by calling the :class:`Noddy` class::
-
- >>> import noddy
- >>> mynoddy = noddy.Noddy()
-
-That's it! All that remains is to build it; put the above code in a file called
-:file:`noddy.c` and ::
-
- from distutils.core import setup, Extension
- setup(name="noddy", version="1.0",
- ext_modules=[Extension("noddy", ["noddy.c"])])
-
-in a file called :file:`setup.py`; then typing
-
-.. code-block:: shell-session
-
- $ python setup.py build
-
-at a shell should produce a file :file:`noddy.so` in a subdirectory; move to
-that directory and fire up Python --- you should be able to ``import noddy`` and
-play around with Noddy objects.
-
-That wasn't so hard, was it?
-
-Of course, the current Noddy type is pretty uninteresting. It has no data and
-doesn't do anything. It can't even be subclassed.
-
-
-Adding data and methods to the Basic example
---------------------------------------------
-
-Let's extend the basic example to add some data and methods. Let's also make
-the type usable as a base class. We'll create a new module, :mod:`noddy2` that
-adds these capabilities:
-
-.. literalinclude:: ../includes/noddy2.c
-
-
-This version of the module has a number of changes.
-
-We've added an extra include::
-
- #include
-
-This include provides declarations that we use to handle attributes, as
-described a bit later.
-
-The name of the :class:`Noddy` object structure has been shortened to
-:class:`Noddy`. The type object name has been shortened to :class:`NoddyType`.
-
-The :class:`Noddy` type now has three data attributes, *first*, *last*, and
-*number*. The *first* and *last* variables are Python strings containing first
-and last names. The *number* attribute is an integer.
-
-The object structure is updated accordingly::
-
- typedef struct {
- PyObject_HEAD
- PyObject *first;
- PyObject *last;
- int number;
- } Noddy;
-
-Because we now have data to manage, we have to be more careful about object
-allocation and deallocation. At a minimum, we need a deallocation method::
-
- static void
- Noddy_dealloc(Noddy* self)
- {
- Py_XDECREF(self->first);
- Py_XDECREF(self->last);
- Py_TYPE(self)->tp_free((PyObject*)self);
- }
-
-which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::
-
- (destructor)Noddy_dealloc, /*tp_dealloc*/
-
-This method decrements the reference counts of the two Python attributes. We use
-:c:func:`Py_XDECREF` here because the :attr:`first` and :attr:`last` members
-could be *NULL*. It then calls the :c:member:`~PyTypeObject.tp_free` member of the object's type
-to free the object's memory. Note that the object's type might not be
-:class:`NoddyType`, because the object may be an instance of a subclass.
-
-We want to make sure that the first and last names are initialized to empty
-strings, so we provide a new method::
-
- static PyObject *
- Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
- }
-
-and install it in the :c:member:`~PyTypeObject.tp_new` member::
-
- Noddy_new, /* tp_new */
-
-The new member is responsible for creating (as opposed to initializing) objects
-of the type. It is exposed in Python as the :meth:`__new__` method. See the
-paper titled "Unifying types and classes in Python" for a detailed discussion of
-the :meth:`__new__` method. One reason to implement a new method is to assure
-the initial values of instance variables. In this case, we use the new method
-to make sure that the initial values of the members :attr:`first` and
-:attr:`last` are not *NULL*. If we didn't care whether the initial values were
-*NULL*, we could have used :c:func:`PyType_GenericNew` as our new method, as we
-did before. :c:func:`PyType_GenericNew` initializes all of the instance variable
-members to *NULL*.
-
-The new method is a static method that is passed the type being instantiated and
-any arguments passed when the type was called, and that returns the new object
-created. New methods always accept positional and keyword arguments, but they
-often ignore the arguments, leaving the argument handling to initializer
-methods. Note that if the type supports subclassing, the type passed may not be
-the type being defined. The new method calls the :c:member:`~PyTypeObject.tp_alloc` slot to
-allocate memory. We don't fill the :c:member:`~PyTypeObject.tp_alloc` slot ourselves. Rather
-:c:func:`PyType_Ready` fills it for us by inheriting it from our base class,
-which is :class:`object` by default. Most types use the default allocation.
-
-.. note::
-
- If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one that calls a base type's
- :c:member:`~PyTypeObject.tp_new` or :meth:`__new__`), you must *not* try to determine what method
- to call using method resolution order at runtime. Always statically determine
- what type you are going to call, and call its :c:member:`~PyTypeObject.tp_new` directly, or via
- ``type->tp_base->tp_new``. If you do not do this, Python subclasses of your
- type that also inherit from other Python-defined classes may not work correctly.
- (Specifically, you may not be able to create instances of such subclasses
- without getting a :exc:`TypeError`.)
-
-We provide an initialization function::
-
- static int
- Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
- {
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_XDECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_XDECREF(tmp);
- }
-
- return 0;
- }
-
-by filling the :c:member:`~PyTypeObject.tp_init` slot. ::
-
- (initproc)Noddy_init, /* tp_init */
-
-The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the :meth:`__init__` method. It
-is used to initialize an object after it's created. Unlike the new method, we
-can't guarantee that the initializer is called. The initializer isn't called
-when unpickling objects and it can be overridden. Our initializer accepts
-arguments to provide initial values for our instance. Initializers always accept
-positional and keyword arguments. Initializers should return either 0 on
-success or -1 on error.
-
-Initializers can be called multiple times. Anyone can call the :meth:`__init__`
-method on our objects. For this reason, we have to be extra careful when
-assigning the new values. We might be tempted, for example to assign the
-:attr:`first` member like this::
-
- if (first) {
- Py_XDECREF(self->first);
- Py_INCREF(first);
- self->first = first;
- }
-
-But this would be risky. Our type doesn't restrict the type of the
-:attr:`first` member, so it could be any kind of object. It could have a
-destructor that causes code to be executed that tries to access the
-:attr:`first` member. To be paranoid and protect ourselves against this
-possibility, we almost always reassign members before decrementing their
-reference counts. When don't we have to do this?
-
-* when we absolutely know that the reference count is greater than 1
-
-* when we know that deallocation of the object [#]_ will not cause any calls
- back into our type's code
-
-* when decrementing a reference count in a :c:member:`~PyTypeObject.tp_dealloc` handler when
- garbage-collections is not supported [#]_
-
-We want to expose our instance variables as attributes. There are a
-number of ways to do that. The simplest way is to define member definitions::
-
- static PyMemberDef Noddy_members[] = {
- {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
- "first name"},
- {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
- "last name"},
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
- };
-
-and put the definitions in the :c:member:`~PyTypeObject.tp_members` slot::
-
- Noddy_members, /* tp_members */
-
-Each member definition has a member name, type, offset, access flags and
-documentation string. See the :ref:`Generic-Attribute-Management` section below for
-details.
-
-A disadvantage of this approach is that it doesn't provide a way to restrict the
-types of objects that can be assigned to the Python attributes. We expect the
-first and last names to be strings, but any Python objects can be assigned.
-Further, the attributes can be deleted, setting the C pointers to *NULL*. Even
-though we can make sure the members are initialized to non-*NULL* values, the
-members can be set to *NULL* if the attributes are deleted.
-
-We define a single method, :meth:`name`, that outputs the objects name as the
-concatenation of the first and last names. ::
-
- static PyObject *
- Noddy_name(Noddy* self)
- {
- if (self->first == NULL) {
- PyErr_SetString(PyExc_AttributeError, "first");
- return NULL;
- }
-
- if (self->last == NULL) {
- PyErr_SetString(PyExc_AttributeError, "last");
- return NULL;
- }
-
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
- }
-
-The method is implemented as a C function that takes a :class:`Noddy` (or
-:class:`Noddy` subclass) instance as the first argument. Methods always take an
-instance as the first argument. Methods often take positional and keyword
-arguments as well, but in this case we don't take any and don't need to accept
-a positional argument tuple or keyword argument dictionary. This method is
-equivalent to the Python method::
-
- def name(self):
- return "%s %s" % (self.first, self.last)
-
-Note that we have to check for the possibility that our :attr:`first` and
-:attr:`last` members are *NULL*. This is because they can be deleted, in which
-case they are set to *NULL*. It would be better to prevent deletion of these
-attributes and to restrict the attribute values to be strings. We'll see how to
-do that in the next section.
-
-Now that we've defined the method, we need to create an array of method
-definitions::
-
- static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
- };
-
-and assign them to the :c:member:`~PyTypeObject.tp_methods` slot::
-
- Noddy_methods, /* tp_methods */
-
-Note that we used the :const:`METH_NOARGS` flag to indicate that the method is
-passed no arguments.
-
-Finally, we'll make our type usable as a base class. We've written our methods
-carefully so far so that they don't make any assumptions about the type of the
-object being created or used, so all we need to do is to add the
-:const:`Py_TPFLAGS_BASETYPE` to our class flag definition::
-
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
-
-We rename :c:func:`PyInit_noddy` to :c:func:`PyInit_noddy2` and update the module
-name in the :c:type:`PyModuleDef` struct.
-
-Finally, we update our :file:`setup.py` file to build the new module::
-
- from distutils.core import setup, Extension
- setup(name="noddy", version="1.0",
- ext_modules=[
- Extension("noddy", ["noddy.c"]),
- Extension("noddy2", ["noddy2.c"]),
- ])
-
-
-Providing finer control over data attributes
---------------------------------------------
-
-In this section, we'll provide finer control over how the :attr:`first` and
-:attr:`last` attributes are set in the :class:`Noddy` example. In the previous
-version of our module, the instance variables :attr:`first` and :attr:`last`
-could be set to non-string values or even deleted. We want to make sure that
-these attributes always contain strings.
-
-.. literalinclude:: ../includes/noddy3.c
-
-
-To provide greater control, over the :attr:`first` and :attr:`last` attributes,
-we'll use custom getter and setter functions. Here are the functions for
-getting and setting the :attr:`first` attribute::
-
- Noddy_getfirst(Noddy *self, void *closure)
- {
- Py_INCREF(self->first);
- return self->first;
- }
-
- static int
- Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
- {
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
- return -1;
- }
-
- if (! PyUnicode_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The first attribute value must be a str");
- return -1;
- }
-
- Py_DECREF(self->first);
- Py_INCREF(value);
- self->first = value;
-
- return 0;
- }
-
-The getter function is passed a :class:`Noddy` object and a "closure", which is
-void pointer. In this case, the closure is ignored. (The closure supports an
-advanced usage in which definition data is passed to the getter and setter. This
-could, for example, be used to allow a single set of getter and setter functions
-that decide the attribute to get or set based on data in the closure.)
-
-The setter function is passed the :class:`Noddy` object, the new value, and the
-closure. The new value may be *NULL*, in which case the attribute is being
-deleted. In our setter, we raise an error if the attribute is deleted or if the
-attribute value is not a string.
-
-We create an array of :c:type:`PyGetSetDef` structures::
-
- static PyGetSetDef Noddy_getseters[] = {
- {"first",
- (getter)Noddy_getfirst, (setter)Noddy_setfirst,
- "first name",
- NULL},
- {"last",
- (getter)Noddy_getlast, (setter)Noddy_setlast,
- "last name",
- NULL},
- {NULL} /* Sentinel */
- };
-
-and register it in the :c:member:`~PyTypeObject.tp_getset` slot::
-
- Noddy_getseters, /* tp_getset */
-
-to register our attribute getters and setters.
-
-The last item in a :c:type:`PyGetSetDef` structure is the closure mentioned
-above. In this case, we aren't using the closure, so we just pass *NULL*.
-
-We also remove the member definitions for these attributes::
-
- static PyMemberDef Noddy_members[] = {
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
- };
-
-We also need to update the :c:member:`~PyTypeObject.tp_init` handler to only allow strings [#]_ to
-be passed::
-
- static int
- Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
- {
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_DECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_DECREF(tmp);
- }
-
- return 0;
- }
-
-With these changes, we can assure that the :attr:`first` and :attr:`last`
-members are never *NULL* so we can remove checks for *NULL* values in almost all
-cases. This means that most of the :c:func:`Py_XDECREF` calls can be converted to
-:c:func:`Py_DECREF` calls. The only place we can't change these calls is in the
-deallocator, where there is the possibility that the initialization of these
-members failed in the constructor.
-
-We also rename the module initialization function and module name in the
-initialization function, as we did before, and we add an extra definition to the
-:file:`setup.py` file.
-
-
-Supporting cyclic garbage collection
-------------------------------------
-
-Python has a cyclic-garbage collector that can identify unneeded objects even
-when their reference counts are not zero. This can happen when objects are
-involved in cycles. For example, consider::
-
- >>> l = []
- >>> l.append(l)
- >>> del l
-
-In this example, we create a list that contains itself. When we delete it, it
-still has a reference from itself. Its reference count doesn't drop to zero.
-Fortunately, Python's cyclic-garbage collector will eventually figure out that
-the list is garbage and free it.
-
-In the second version of the :class:`Noddy` example, we allowed any kind of
-object to be stored in the :attr:`first` or :attr:`last` attributes [#]_. This
-means that :class:`Noddy` objects can participate in cycles::
-
- >>> import noddy2
- >>> n = noddy2.Noddy()
- >>> l = [n]
- >>> n.first = l
-
-This is pretty silly, but it gives us an excuse to add support for the
-cyclic-garbage collector to the :class:`Noddy` example. To support cyclic
-garbage collection, types need to fill two slots and set a class flag that
-enables these slots:
-
-.. literalinclude:: ../includes/noddy4.c
-
-
-The traversal method provides access to subobjects that could participate in
-cycles::
-
- static int
- Noddy_traverse(Noddy *self, visitproc visit, void *arg)
- {
- int vret;
-
- if (self->first) {
- vret = visit(self->first, arg);
- if (vret != 0)
- return vret;
- }
- if (self->last) {
- vret = visit(self->last, arg);
- if (vret != 0)
- return vret;
- }
-
- return 0;
- }
-
-For each subobject that can participate in cycles, we need to call the
-:c:func:`visit` function, which is passed to the traversal method. The
-:c:func:`visit` function takes as arguments the subobject and the extra argument
-*arg* passed to the traversal method. It returns an integer value that must be
-returned if it is non-zero.
-
-Python provides a :c:func:`Py_VISIT` macro that automates calling visit
-functions. With :c:func:`Py_VISIT`, :c:func:`Noddy_traverse` can be simplified::
-
- static int
- Noddy_traverse(Noddy *self, visitproc visit, void *arg)
- {
- Py_VISIT(self->first);
- Py_VISIT(self->last);
- return 0;
- }
-
-.. note::
-
- Note that the :c:member:`~PyTypeObject.tp_traverse` implementation must name its arguments exactly
- *visit* and *arg* in order to use :c:func:`Py_VISIT`. This is to encourage
- uniformity across these boring implementations.
-
-We also need to provide a method for clearing any subobjects that can
-participate in cycles.
-
-::
-
- static int
- Noddy_clear(Noddy *self)
- {
- PyObject *tmp;
-
- tmp = self->first;
- self->first = NULL;
- Py_XDECREF(tmp);
-
- tmp = self->last;
- self->last = NULL;
- Py_XDECREF(tmp);
-
- return 0;
- }
-
-Notice the use of a temporary variable in :c:func:`Noddy_clear`. We use the
-temporary variable so that we can set each member to *NULL* before decrementing
-its reference count. We do this because, as was discussed earlier, if the
-reference count drops to zero, we might cause code to run that calls back into
-the object. In addition, because we now support garbage collection, we also
-have to worry about code being run that triggers garbage collection. If garbage
-collection is run, our :c:member:`~PyTypeObject.tp_traverse` handler could get called. We can't
-take a chance of having :c:func:`Noddy_traverse` called when a member's reference
-count has dropped to zero and its value hasn't been set to *NULL*.
-
-Python provides a :c:func:`Py_CLEAR` that automates the careful decrementing of
-reference counts. With :c:func:`Py_CLEAR`, the :c:func:`Noddy_clear` function can
-be simplified::
-
- static int
- Noddy_clear(Noddy *self)
- {
- Py_CLEAR(self->first);
- Py_CLEAR(self->last);
- return 0;
- }
-
-Note that :c:func:`Noddy_dealloc` may call arbitrary functions through
-``__del__`` method or weakref callback. It means circular GC can be
-triggered inside the function. Since GC assumes reference count is not zero,
-we need to untrack the object from GC by calling :c:func:`PyObject_GC_UnTrack`
-before clearing members. Here is reimplemented deallocator which uses
-:c:func:`PyObject_GC_UnTrack` and :c:func:`Noddy_clear`.
-
-::
-
- static void
- Noddy_dealloc(Noddy* self)
- {
- PyObject_GC_UnTrack(self);
- Noddy_clear(self);
- Py_TYPE(self)->tp_free((PyObject*)self);
- }
-
-Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::
-
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
-
-That's pretty much it. If we had written custom :c:member:`~PyTypeObject.tp_alloc` or
-:c:member:`~PyTypeObject.tp_free` slots, we'd need to modify them for cyclic-garbage collection.
-Most extensions will use the versions automatically provided.
-
-
-Subclassing other types
------------------------
-
-It is possible to create new extension types that are derived from existing
-types. It is easiest to inherit from the built in types, since an extension can
-easily use the :class:`PyTypeObject` it needs. It can be difficult to share
-these :class:`PyTypeObject` structures between extension modules.
-
-In this example we will create a :class:`Shoddy` type that inherits from the
-built-in :class:`list` type. The new type will be completely compatible with
-regular lists, but will have an additional :meth:`increment` method that
-increases an internal counter. ::
-
- >>> import shoddy
- >>> s = shoddy.Shoddy(range(3))
- >>> s.extend(s)
- >>> print(len(s))
- 6
- >>> print(s.increment())
- 1
- >>> print(s.increment())
- 2
-
-.. literalinclude:: ../includes/shoddy.c
-
-
-As you can see, the source code closely resembles the :class:`Noddy` examples in
-previous sections. We will break down the main differences between them. ::
-
- typedef struct {
- PyListObject list;
- int state;
- } Shoddy;
-
-The primary difference for derived type objects is that the base type's object
-structure must be the first value. The base type will already include the
-:c:func:`PyObject_HEAD` at the beginning of its structure.
-
-When a Python object is a :class:`Shoddy` instance, its *PyObject\** pointer can
-be safely cast to both *PyListObject\** and *Shoddy\**. ::
-
- static int
- Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
- {
- if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
- return -1;
- self->state = 0;
- return 0;
- }
-
-In the :attr:`__init__` method for our type, we can see how to call through to
-the :attr:`__init__` method of the base type.
-
-This pattern is important when writing a type with custom :attr:`new` and
-:attr:`dealloc` methods. The :attr:`new` method should not actually create the
-memory for the object with :c:member:`~PyTypeObject.tp_alloc`, that will be handled by the base
-class when calling its :c:member:`~PyTypeObject.tp_new`.
-
-When filling out the :c:func:`PyTypeObject` for the :class:`Shoddy` type, you see
-a slot for :c:func:`tp_base`. Due to cross platform compiler issues, you can't
-fill that field directly with the :c:func:`PyList_Type`; it can be done later in
-the module's :c:func:`init` function. ::
-
- PyMODINIT_FUNC
- PyInit_shoddy(void)
- {
- PyObject *m;
-
- ShoddyType.tp_base = &PyList_Type;
- if (PyType_Ready(&ShoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&shoddymodule);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&ShoddyType);
- PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
- return m;
- }
-
-Before calling :c:func:`PyType_Ready`, the type structure must have the
-:c:member:`~PyTypeObject.tp_base` slot filled in. When we are deriving a new type, it is not
-necessary to fill out the :c:member:`~PyTypeObject.tp_alloc` slot with :c:func:`PyType_GenericNew`
--- the allocate function from the base type will be inherited.
-
-After that, calling :c:func:`PyType_Ready` and adding the type object to the
-module is the same as with the basic :class:`Noddy` examples.
-
+*****************************************
+Defining Extension Types: Assorted Topics
+*****************************************
.. _dnt-type-methods:
-Type Methods
-============
-
This section aims to give a quick fly-by on the various type methods you can
implement and what they do.
@@ -893,21 +15,20 @@ debug builds omitted:
.. literalinclude:: ../includes/typestruct.h
-Now that's a *lot* of methods. Don't worry too much though - if you have a type
-you want to define, the chances are very good that you will only implement a
-handful of these.
+Now that's a *lot* of methods. Don't worry too much though -- if you have
+a type you want to define, the chances are very good that you will only
+implement a handful of these.
As you probably expect by now, we're going to go over this and give more
information about the various handlers. We won't go in the order they are
defined in the structure, because there is a lot of historical baggage that
-impacts the ordering of the fields; be sure your type initialization keeps the
-fields in the right order! It's often easiest to find an example that includes
-all the fields you need (even if they're initialized to ``0``) and then change
-the values to suit your new type. ::
+impacts the ordering of the fields. It's often easiest to find an example
+that includes the fields you need and then change the values to suit your new
+type. ::
const char *tp_name; /* For printing */
-The name of the type - as mentioned in the last section, this will appear in
+The name of the type -- as mentioned in the previous chapter, this will appear in
various places, almost entirely for diagnostic purposes. Try to choose something
that will be helpful in such a situation! ::
@@ -915,7 +36,7 @@ that will be helpful in such a situation! ::
These fields tell the runtime how much memory to allocate when new objects of
this type are created. Python has some built-in support for variable length
-structures (think: strings, lists) which is where the :c:member:`~PyTypeObject.tp_itemsize` field
+structures (think: strings, tuples) which is where the :c:member:`~PyTypeObject.tp_itemsize` field
comes in. This will be dealt with later. ::
const char *tp_doc;
@@ -923,7 +44,7 @@ comes in. This will be dealt with later. ::
Here you can put a string (or its address) that you want returned when the
Python script references ``obj.__doc__`` to retrieve the doc string.
-Now we come to the basic type methods---the ones most extension types will
+Now we come to the basic type methods -- the ones most extension types will
implement.
@@ -947,7 +68,7 @@ object itself needs to be freed here as well. Here is an example of this
function::
static void
- newdatatype_dealloc(newdatatypeobject * obj)
+ newdatatype_dealloc(newdatatypeobject *obj)
{
free(obj->obj_UnderlyingDatatypePtr);
Py_TYPE(obj)->tp_free(obj);
@@ -1035,7 +156,7 @@ example::
static PyObject *
newdatatype_repr(newdatatypeobject * obj)
{
- return PyUnicode_FromFormat("Repr-ified_newdatatype{{size:\%d}}",
+ return PyUnicode_FromFormat("Repr-ified_newdatatype{{size:%d}}",
obj->obj_UnderlyingDatatypePtr->size);
}
@@ -1055,7 +176,7 @@ Here is a simple example::
static PyObject *
newdatatype_str(newdatatypeobject * obj)
{
- return PyUnicode_FromFormat("Stringified_newdatatype{{size:\%d}}",
+ return PyUnicode_FromFormat("Stringified_newdatatype{{size:%d}}",
obj->obj_UnderlyingDatatypePtr->size);
}
@@ -1068,7 +189,7 @@ For every object which can support attributes, the corresponding type must
provide the functions that control how the attributes are resolved. There needs
to be a function which can retrieve attributes (if any are defined), and another
to set attributes (if setting attributes is allowed). Removing an attribute is
-a special case, for which the new value passed to the handler is *NULL*.
+a special case, for which the new value passed to the handler is ``NULL``.
Python supports two pairs of attribute handlers; a type that supports attributes
only needs to implement the functions for one pair. The difference is that one
@@ -1110,9 +231,9 @@ attributes, when the values are computed, or how relevant data is stored.
When :c:func:`PyType_Ready` is called, it uses three tables referenced by the
type object to create :term:`descriptor`\s which are placed in the dictionary of the
type object. Each descriptor controls access to one attribute of the instance
-object. Each of the tables is optional; if all three are *NULL*, instances of
+object. Each of the tables is optional; if all three are ``NULL``, instances of
the type will only have attributes that are inherited from their base type, and
-should leave the :c:member:`~PyTypeObject.tp_getattro` and :c:member:`~PyTypeObject.tp_setattro` fields *NULL* as
+should leave the :c:member:`~PyTypeObject.tp_getattro` and :c:member:`~PyTypeObject.tp_setattro` fields ``NULL`` as
well, allowing the base type to handle attributes.
The tables are declared as three fields of the type object::
@@ -1121,7 +242,7 @@ The tables are declared as three fields of the type object::
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
-If :c:member:`~PyTypeObject.tp_methods` is not *NULL*, it must refer to an array of
+If :c:member:`~PyTypeObject.tp_methods` is not ``NULL``, it must refer to an array of
:c:type:`PyMethodDef` structures. Each entry in the table is an instance of this
structure::
@@ -1135,7 +256,7 @@ structure::
One entry should be defined for each method provided by the type; no entries are
needed for methods inherited from a base type. One additional entry is needed
at the end; it is a sentinel that marks the end of the array. The
-:attr:`ml_name` field of the sentinel must be *NULL*.
+:attr:`ml_name` field of the sentinel must be ``NULL``.
The second table is used to define attributes which map directly to data stored
in the instance. A variety of primitive C types are supported, and access may
@@ -1184,7 +305,7 @@ application can use the introspection API to retrieve the descriptor from the
class object, and get the doc string using its :attr:`__doc__` attribute.
As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry with a :attr:`name` value
-of *NULL* is required.
+of ``NULL`` is required.
.. XXX Descriptors need to be explained in more detail somewhere, but not here.
@@ -1229,14 +350,14 @@ Here is an example::
The :c:member:`~PyTypeObject.tp_setattr` handler is called when the :meth:`__setattr__` or
:meth:`__delattr__` method of a class instance would be called. When an
-attribute should be deleted, the third parameter will be *NULL*. Here is an
+attribute should be deleted, the third parameter will be ``NULL``. Here is an
example that simply raises an exception; if this were really all you wanted, the
-:c:member:`~PyTypeObject.tp_setattr` handler should be set to *NULL*. ::
+:c:member:`~PyTypeObject.tp_setattr` handler should be set to ``NULL``. ::
static int
newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v)
{
- (void)PyErr_Format(PyExc_RuntimeError, "Read-only attribute: \%s", name);
+ PyErr_Format(PyExc_RuntimeError, "Read-only attribute: %s", name);
return -1;
}
@@ -1257,7 +378,7 @@ where the operator is one of ``Py_EQ``, ``Py_NE``, ``Py_LE``, ``Py_GT``,
``Py_LT`` or ``Py_GT``. It should compare the two objects with respect to the
specified operator and return ``Py_True`` or ``Py_False`` if the comparison is
successful, ``Py_NotImplemented`` to indicate that comparison is not
-implemented and the other object's comparison method should be tried, or *NULL*
+implemented and the other object's comparison method should be tried, or ``NULL``
if an exception was set.
Here is a sample implementation, for a datatype that is considered equal if the
@@ -1304,7 +425,7 @@ from the type implementation, the older protocols have been defined as optional
blocks of handlers referenced by the type object. For newer protocols there are
additional slots in the main type object, with a flag bit being set to indicate
that the slots are present and should be checked by the interpreter. (The flag
-bit does not indicate that the slot values are non-*NULL*. The flag may be set
+bit does not indicate that the slot values are non-``NULL``. The flag may be set
to indicate the presence of a slot, but a slot may still be unfilled.) ::
PyNumberMethods *tp_as_number;
@@ -1321,17 +442,23 @@ these in the :file:`Objects` directory of the Python source distribution. ::
hashfunc tp_hash;
This function, if you choose to provide it, should return a hash number for an
-instance of your data type. Here is a moderately pointless example::
+instance of your data type. Here is a simple example::
- static long
+ static Py_hash_t
newdatatype_hash(newdatatypeobject *obj)
{
- long result;
- result = obj->obj_UnderlyingDatatypePtr->size;
- result = result * 3;
+ Py_hash_t result;
+ result = obj->some_size + 32767 * obj->some_number;
+ if (result == -1)
+ result = -2;
return result;
}
+:c:type:`Py_hash_t` is a signed integer type with a platform-varying width.
+Returning ``-1`` from :c:member:`~PyTypeObject.tp_hash` indicates an error,
+which is why you should be careful to avoid returning it when hash computation
+is successful, as seen above.
+
::
ternaryfunc tp_call;
@@ -1342,27 +469,22 @@ contains ``obj1('hello')``, the :c:member:`~PyTypeObject.tp_call` handler is inv
This function takes three arguments:
-#. *arg1* is the instance of the data type which is the subject of the call. If
- the call is ``obj1('hello')``, then *arg1* is ``obj1``.
+#. *self* is the instance of the data type which is the subject of the call.
+ If the call is ``obj1('hello')``, then *self* is ``obj1``.
-#. *arg2* is a tuple containing the arguments to the call. You can use
+#. *args* is a tuple containing the arguments to the call. You can use
:c:func:`PyArg_ParseTuple` to extract the arguments.
-#. *arg3* is a dictionary of keyword arguments that were passed. If this is
- non-*NULL* and you support keyword arguments, use
- :c:func:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you do not
- want to support keyword arguments and this is non-*NULL*, raise a
+#. *kwds* is a dictionary of keyword arguments that were passed. If this is
+ non-``NULL`` and you support keyword arguments, use
+ :c:func:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you
+ do not want to support keyword arguments and this is non-``NULL``, raise a
:exc:`TypeError` with a message saying that keyword arguments are not supported.
-Here is a desultory example of the implementation of the call function. ::
+Here is a toy ``tp_call`` implementation::
- /* Implement the call function.
- * obj1 is the instance receiving the call.
- * obj2 is a tuple containing the arguments to the call, in this
- * case 3 strings.
- */
static PyObject *
- newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *other)
+ newdatatype_call(newdatatypeobject *self, PyObject *args, PyObject *kwds)
{
PyObject *result;
const char *arg1;
@@ -1373,7 +495,7 @@ Here is a desultory example of the implementation of the call function. ::
return NULL;
}
result = PyUnicode_FromFormat(
- "Returning -- value: [\%d] arg1: [\%s] arg2: [\%s] arg3: [\%s]\n",
+ "Returning -- value: [%d] arg1: [%s] arg2: [%s] arg3: [%s]\n",
obj->obj_UnderlyingDatatypePtr->size,
arg1, arg2, arg3);
return result;
@@ -1385,32 +507,36 @@ Here is a desultory example of the implementation of the call function. ::
getiterfunc tp_iter;
iternextfunc tp_iternext;
-These functions provide support for the iterator protocol. Any object which
-wishes to support iteration over its contents (which may be generated during
-iteration) must implement the ``tp_iter`` handler. Objects which are returned
-by a ``tp_iter`` handler must implement both the ``tp_iter`` and ``tp_iternext``
-handlers. Both handlers take exactly one parameter, the instance for which they
-are being called, and return a new reference. In the case of an error, they
-should set an exception and return *NULL*.
-
-For an object which represents an iterable collection, the ``tp_iter`` handler
-must return an iterator object. The iterator object is responsible for
-maintaining the state of the iteration. For collections which can support
-multiple iterators which do not interfere with each other (as lists and tuples
-do), a new iterator should be created and returned. Objects which can only be
-iterated over once (usually due to side effects of iteration) should implement
-this handler by returning a new reference to themselves, and should also
-implement the ``tp_iternext`` handler. File objects are an example of such an
-iterator.
-
-Iterator objects should implement both handlers. The ``tp_iter`` handler should
-return a new reference to the iterator (this is the same as the ``tp_iter``
-handler for objects which can only be iterated over destructively). The
-``tp_iternext`` handler should return a new reference to the next object in the
-iteration if there is one. If the iteration has reached the end, it may return
-*NULL* without setting an exception or it may set :exc:`StopIteration`; avoiding
-the exception can yield slightly better performance. If an actual error occurs,
-it should set an exception and return *NULL*.
+These functions provide support for the iterator protocol. Both handlers
+take exactly one parameter, the instance for which they are being called,
+and return a new reference. In the case of an error, they should set an
+exception and return ``NULL``. :c:member:`~PyTypeObject.tp_iter` corresponds
+to the Python :meth:`__iter__` method, while :c:member:`~PyTypeObject.tp_iternext`
+corresponds to the Python :meth:`~iterator.__next__` method.
+
+Any :term:`iterable` object must implement the :c:member:`~PyTypeObject.tp_iter`
+handler, which must return an :term:`iterator` object. Here the same guidelines
+apply as for Python classes:
+
+* For collections (such as lists and tuples) which can support multiple
+ independent iterators, a new iterator should be created and returned by
+ each call to :c:member:`~PyTypeObject.tp_iter`.
+* Objects which can only be iterated over once (usually due to side effects of
+ iteration, such as file objects) can implement :c:member:`~PyTypeObject.tp_iter`
+ by returning a new reference to themselves -- and should also therefore
+ implement the :c:member:`~PyTypeObject.tp_iternext` handler.
+
+Any :term:`iterator` object should implement both :c:member:`~PyTypeObject.tp_iter`
+and :c:member:`~PyTypeObject.tp_iternext`. An iterator's
+:c:member:`~PyTypeObject.tp_iter` handler should return a new reference
+to the iterator. Its :c:member:`~PyTypeObject.tp_iternext` handler should
+return a new reference to the next object in the iteration, if there is one.
+If the iteration has reached the end, :c:member:`~PyTypeObject.tp_iternext`
+may return ``NULL`` without setting an exception, or it may set
+:exc:`StopIteration` *in addition* to returning ``NULL``; avoiding
+the exception can yield slightly better performance. If an actual error
+occurs, :c:member:`~PyTypeObject.tp_iternext` should always set an exception
+and return ``NULL``.
.. _weakref-support:
@@ -1418,110 +544,76 @@ it should set an exception and return *NULL*.
Weak Reference Support
----------------------
-One of the goals of Python's weak-reference implementation is to allow any type
+One of the goals of Python's weak reference implementation is to allow any type
to participate in the weak reference mechanism without incurring the overhead on
-those objects which do not benefit by weak referencing (such as numbers).
+performance-critical objects (such as numbers).
-For an object to be weakly referencable, the extension must include a
-:c:type:`PyObject\*` field in the instance structure for the use of the weak
-reference mechanism; it must be initialized to *NULL* by the object's
-constructor. It must also set the :c:member:`~PyTypeObject.tp_weaklistoffset` field of the
-corresponding type object to the offset of the field. For example, the instance
-type is defined with the following structure::
+.. seealso::
+ Documentation for the :mod:`weakref` module.
- typedef struct {
- PyObject_HEAD
- PyClassObject *in_class; /* The class object */
- PyObject *in_dict; /* A dictionary */
- PyObject *in_weakreflist; /* List of weak references */
- } PyInstanceObject;
-
-The statically-declared type object for instances is defined this way::
-
- PyTypeObject PyInstance_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- 0,
- "module.instance",
-
- /* Lots of stuff omitted for brevity... */
-
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
- };
+For an object to be weakly referencable, the extension type must do two things:
-The type constructor is responsible for initializing the weak reference list to
-*NULL*::
+#. Include a :c:type:`PyObject\*` field in the C object structure dedicated to
+ the weak reference mechanism. The object's constructor should leave it
+ ``NULL`` (which is automatic when using the default
+ :c:member:`~PyTypeObject.tp_alloc`).
- static PyObject *
- instance_new() {
- /* Other initialization stuff omitted for brevity */
+#. Set the :c:member:`~PyTypeObject.tp_weaklistoffset` type member
+ to the offset of the aforementioned field in the C object structure,
+ so that the interpreter knows how to access and modify that field.
- self->in_weakreflist = NULL;
+Concretely, here is how a trivial object structure would be augmented
+with the required field::
- return (PyObject *) self;
- }
+ typedef struct {
+ PyObject_HEAD
+ PyObject *weakreflist; /* List of weak references */
+ } TrivialObject;
-The only further addition is that the destructor needs to call the weak
-reference manager to clear any weak references. This is only required if the
-weak reference list is non-*NULL*::
+And the corresponding member in the statically-declared type object::
- static void
- instance_dealloc(PyInstanceObject *inst)
- {
- /* Allocate temporaries if needed, but do not begin
- destruction just yet.
- */
+ static PyTypeObject TrivialType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /* ... other members omitted for brevity ... */
+ .tp_weaklistoffset = offsetof(TrivialObject, weakreflist),
+ };
- if (inst->in_weakreflist != NULL)
- PyObject_ClearWeakRefs((PyObject *) inst);
+The only further addition is that ``tp_dealloc`` needs to clear any weak
+references (by calling :c:func:`PyObject_ClearWeakRefs`) if the field is
+non-``NULL``::
- /* Proceed with object destruction normally. */
+ static void
+ Trivial_dealloc(TrivialObject *self)
+ {
+ /* Clear weakrefs first before calling any destructors */
+ if (self->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) self);
+ /* ... remainder of destruction code omitted for brevity ... */
+ Py_TYPE(self)->tp_free((PyObject *) self);
}
More Suggestions
----------------
-Remember that you can omit most of these functions, in which case you provide
-``0`` as a value. There are type definitions for each of the functions you must
-provide. They are in :file:`object.h` in the Python include directory that
-comes with the source distribution of Python.
-
In order to learn how to implement any specific method for your new data type,
-do the following: Download and unpack the Python source distribution. Go to
-the :file:`Objects` directory, then search the C source files for ``tp_`` plus
-the function you want (for example, ``tp_richcompare``). You will find examples
-of the function you want to implement.
+get the :term:`CPython` source code. Go to the :file:`Objects` directory,
+then search the C source files for ``tp_`` plus the function you want
+(for example, ``tp_richcompare``). You will find examples of the function
+you want to implement.
-When you need to verify that an object is an instance of the type you are
-implementing, use the :c:func:`PyObject_TypeCheck` function. A sample of its use
-might be something like the following::
+When you need to verify that an object is a concrete instance of the type you
+are implementing, use the :c:func:`PyObject_TypeCheck` function. A sample of
+its use might be something like the following::
- if (! PyObject_TypeCheck(some_object, &MyType)) {
+ if (!PyObject_TypeCheck(some_object, &MyType)) {
PyErr_SetString(PyExc_TypeError, "arg #1 not a mything");
return NULL;
}
-.. rubric:: Footnotes
-
-.. [#] This is true when we know that the object is a basic type, like a string or a
- float.
-
-.. [#] We relied on this in the :c:member:`~PyTypeObject.tp_dealloc` handler in this example, because our
- type doesn't support garbage collection. Even if a type supports garbage
- collection, there are calls that can be made to "untrack" the object from
- garbage collection, however, these calls are advanced and not covered here.
-
-.. [#] We now know that the first and last members are strings, so perhaps we could be
- less careful about decrementing their reference counts, however, we accept
- instances of string subclasses. Even though deallocating normal strings won't
- call back into our objects, we can't guarantee that deallocating an instance of
- a string subclass won't call back into our objects.
+.. seealso::
+ Download CPython source releases.
+ https://www.python.org/downloads/source/
-.. [#] Even in the third version, we aren't guaranteed to avoid cycles. Instances of
- string subclasses are allowed and string subclasses could allow cycles even if
- normal strings don't.
+ The CPython project on GitHub, where the CPython source code is developed.
+ https://github.com/python/cpython
diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst
new file mode 100644
index 00000000000000..b314e9e2e15497
--- /dev/null
+++ b/Doc/extending/newtypes_tutorial.rst
@@ -0,0 +1,907 @@
+.. highlightlang:: c
+
+.. _defining-new-types:
+
+**********************************
+Defining Extension Types: Tutorial
+**********************************
+
+.. sectionauthor:: Michael Hudson
+.. sectionauthor:: Dave Kuhlman
+.. sectionauthor:: Jim Fulton
+
+
+Python allows the writer of a C extension module to define new types that
+can be manipulated from Python code, much like the built-in :class:`str`
+and :class:`list` types. The code for all extension types follows a
+pattern, but there are some details that you need to understand before you
+can get started. This document is a gentle introduction to the topic.
+
+
+.. _dnt-basics:
+
+The Basics
+==========
+
+The :term:`CPython` runtime sees all Python objects as variables of type
+:c:type:`PyObject\*`, which serves as a "base type" for all Python objects.
+The :c:type:`PyObject` structure itself only contains the object's
+:term:`reference count` and a pointer to the object's "type object".
+This is where the action is; the type object determines which (C) functions
+get called by the interpreter when, for instance, an attribute gets looked up
+on an object, a method called, or it is multiplied by another object. These
+C functions are called "type methods".
+
+So, if you want to define a new extension type, you need to create a new type
+object.
+
+This sort of thing can only be explained by example, so here's a minimal, but
+complete, module that defines a new type named :class:`Custom` inside a C
+extension module :mod:`custom`:
+
+.. note::
+ What we're showing here is the traditional way of defining *static*
+ extension types. It should be adequate for most uses. The C API also
+ allows defining heap-allocated extension types using the
+ :c:func:`PyType_FromSpec` function, which isn't covered in this tutorial.
+
+.. literalinclude:: ../includes/custom.c
+
+Now that's quite a bit to take in at once, but hopefully bits will seem familiar
+from the previous chapter. This file defines three things:
+
+#. What a :class:`Custom` **object** contains: this is the ``CustomObject``
+ struct, which is allocated once for each :class:`Custom` instance.
+#. How the :class:`Custom` **type** behaves: this is the ``CustomType`` struct,
+ which defines a set of flags and function pointers that the interpreter
+ inspects when specific operations are requested.
+#. How to initialize the :mod:`custom` module: this is the ``PyInit_custom``
+ function and the associated ``custommodule`` struct.
+
+The first bit is::
+
+ typedef struct {
+ PyObject_HEAD
+ } CustomObject;
+
+This is what a Custom object will contain. ``PyObject_HEAD`` is mandatory
+at the start of each object struct and defines a field called ``ob_base``
+of type :c:type:`PyObject`, containing a pointer to a type object and a
+reference count (these can be accessed using the macros :c:macro:`Py_REFCNT`
+and :c:macro:`Py_TYPE` respectively). The reason for the macro is to
+abstract away the layout and to enable additional fields in debug builds.
+
+.. note::
+ There is no semicolon above after the :c:macro:`PyObject_HEAD` macro.
+ Be wary of adding one by accident: some compilers will complain.
+
+Of course, objects generally store additional data besides the standard
+``PyObject_HEAD`` boilerplate; for example, here is the definition for
+standard Python floats::
+
+ typedef struct {
+ PyObject_HEAD
+ double ob_fval;
+ } PyFloatObject;
+
+The second bit is the definition of the type object. ::
+
+ static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_new = PyType_GenericNew,
+ };
+
+.. note::
+ We recommend using C99-style designated initializers as above, to
+ avoid listing all the :c:type:`PyTypeObject` fields that you don't care
+ about and also to avoid caring about the fields' declaration order.
+
+The actual definition of :c:type:`PyTypeObject` in :file:`object.h` has
+many more :ref:`fields ` than the definition above. The
+remaining fields will be filled with zeros by the C compiler, and it's
+common practice to not specify them explicitly unless you need them.
+
+We're going to pick it apart, one field at a time::
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+This line is mandatory boilerplate to initialize the ``ob_base``
+field mentioned above. ::
+
+ .tp_name = "custom.Custom",
+
+The name of our type. This will appear in the default textual representation of
+our objects and in some error messages, for example:
+
+.. code-block:: pycon
+
+ >>> "" + custom.Custom()
+ Traceback (most recent call last):
+ File "", line 1, in
+ TypeError: can only concatenate str (not "custom.Custom") to str
+
+Note that the name is a dotted name that includes both the module name and the
+name of the type within the module. The module in this case is :mod:`custom` and
+the type is :class:`Custom`, so we set the type name to :class:`custom.Custom`.
+Using the real dotted import path is important to make your type compatible
+with the :mod:`pydoc` and :mod:`pickle` modules. ::
+
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+
+This is so that Python knows how much memory to allocate when creating
+new :class:`Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is
+only used for variable-sized objects and should otherwise be zero.
+
+.. note::
+
+ If you want your type to be subclassable from Python, and your type has the same
+ :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have problems with multiple
+ inheritance. A Python subclass of your type will have to list your type first
+ in its :attr:`~class.__bases__`, or else it will not be able to call your type's
+ :meth:`__new__` method without getting an error. You can avoid this problem by
+ ensuring that your type has a larger value for :c:member:`~PyTypeObject.tp_basicsize` than its
+ base type does. Most of the time, this will be true anyway, because either your
+ base type will be :class:`object`, or else you will be adding data members to
+ your base type, and therefore increasing its size.
+
+We set the class flags to :const:`Py_TPFLAGS_DEFAULT`. ::
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+All types should include this constant in their flags. It enables all of the
+members defined until at least Python 3.3. If you need further members,
+you will need to OR the corresponding flags.
+
+We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::
+
+ .tp_doc = "Custom objects",
+
+To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new`
+handler. This is the equivalent of the Python method :meth:`__new__`, but
+has to be specified explicitly. In this case, we can just use the default
+implementation provided by the API function :c:func:`PyType_GenericNew`. ::
+
+ .tp_new = PyType_GenericNew,
+
+Everything else in the file should be familiar, except for some code in
+:c:func:`PyInit_custom`::
+
+ if (PyType_Ready(&CustomType) < 0)
+ return;
+
+This initializes the :class:`Custom` type, filling in a number of members
+to the appropriate default values, including :attr:`ob_type` that we initially
+set to ``NULL``. ::
+
+ Py_INCREF(&CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
+This adds the type to the module dictionary. This allows us to create
+:class:`Custom` instances by calling the :class:`Custom` class:
+
+.. code-block:: pycon
+
+ >>> import custom
+ >>> mycustom = custom.Custom()
+
+That's it! All that remains is to build it; put the above code in a file called
+:file:`custom.c` and:
+
+.. code-block:: python
+
+ from distutils.core import setup, Extension
+ setup(name="custom", version="1.0",
+ ext_modules=[Extension("custom", ["custom.c"])])
+
+in a file called :file:`setup.py`; then typing
+
+.. code-block:: shell-session
+
+ $ python setup.py build
+
+at a shell should produce a file :file:`custom.so` in a subdirectory; move to
+that directory and fire up Python --- you should be able to ``import custom`` and
+play around with Custom objects.
+
+That wasn't so hard, was it?
+
+Of course, the current Custom type is pretty uninteresting. It has no data and
+doesn't do anything. It can't even be subclassed.
+
+.. note::
+ While this documentation showcases the standard :mod:`distutils` module
+ for building C extensions, it is recommended in real-world use cases to
+ use the newer and better-maintained ``setuptools`` library. Documentation
+ on how to do this is out of scope for this document and can be found in
+ the `Python Packaging User's Guide `_.
+
+
+Adding data and methods to the Basic example
+============================================
+
+Let's extend the basic example to add some data and methods. Let's also make
+the type usable as a base class. We'll create a new module, :mod:`custom2` that
+adds these capabilities:
+
+.. literalinclude:: ../includes/custom2.c
+
+
+This version of the module has a number of changes.
+
+We've added an extra include::
+
+ #include
+
+This include provides declarations that we use to handle attributes, as
+described a bit later.
+
+The :class:`Custom` type now has three data attributes in its C struct,
+*first*, *last*, and *number*. The *first* and *last* variables are Python
+strings containing first and last names. The *number* attribute is a C integer.
+
+The object structure is updated accordingly::
+
+ typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+ } CustomObject;
+
+Because we now have data to manage, we have to be more careful about object
+allocation and deallocation. At a minimum, we need a deallocation method::
+
+ static void
+ Custom_dealloc(CustomObject *self)
+ {
+ Py_XDECREF(self->first);
+ Py_XDECREF(self->last);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+ }
+
+which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::
+
+ .tp_dealloc = (destructor) Custom_dealloc,
+
+This method first clears the reference counts of the two Python attributes.
+:c:func:`Py_XDECREF` correctly handles the case where its argument is
+``NULL`` (which might happen here if ``tp_new`` failed midway). It then
+calls the :c:member:`~PyTypeObject.tp_free` member of the object's type
+(computed by ``Py_TYPE(self)``) to free the object's memory. Note that
+the object's type might not be :class:`CustomType`, because the object may
+be an instance of a subclass.
+
+.. note::
+ The explicit cast to ``destructor`` above is needed because we defined
+ ``Custom_dealloc`` to take a ``CustomObject *`` argument, but the ``tp_dealloc``
+ function pointer expects to receive a ``PyObject *`` argument. Otherwise,
+ the compiler will emit a warning. This is object-oriented polymorphism,
+ in C!
+
+We want to make sure that the first and last names are initialized to empty
+strings, so we provide a ``tp_new`` implementation::
+
+ static PyObject *
+ Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+ }
+
+and install it in the :c:member:`~PyTypeObject.tp_new` member::
+
+ .tp_new = Custom_new,
+
+The ``tp_new`` handler is responsible for creating (as opposed to initializing)
+objects of the type. It is exposed in Python as the :meth:`__new__` method.
+It is not required to define a ``tp_new`` member, and indeed many extension
+types will simply reuse :c:func:`PyType_GenericNew` as done in the first
+version of the ``Custom`` type above. In this case, we use the ``tp_new``
+handler to initialize the ``first`` and ``last`` attributes to non-``NULL``
+default values.
+
+``tp_new`` is passed the type being instantiated (not necessarily ``CustomType``,
+if a subclass is instantiated) and any arguments passed when the type was
+called, and is expected to return the instance created. ``tp_new`` handlers
+always accept positional and keyword arguments, but they often ignore the
+arguments, leaving the argument handling to initializer (a.k.a. ``tp_init``
+in C or ``__init__`` in Python) methods.
+
+.. note::
+ ``tp_new`` shouldn't call ``tp_init`` explicitly, as the interpreter
+ will do it itself.
+
+The ``tp_new`` implementation calls the :c:member:`~PyTypeObject.tp_alloc`
+slot to allocate memory::
+
+ self = (CustomObject *) type->tp_alloc(type, 0);
+
+Since memory allocation may fail, we must check the :c:member:`~PyTypeObject.tp_alloc`
+result against ``NULL`` before proceeding.
+
+.. note::
+ We didn't fill the :c:member:`~PyTypeObject.tp_alloc` slot ourselves. Rather
+ :c:func:`PyType_Ready` fills it for us by inheriting it from our base class,
+ which is :class:`object` by default. Most types use the default allocation
+ strategy.
+
+.. note::
+ If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one
+ that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:`__new__`),
+ you must *not* try to determine what method to call using method resolution
+ order at runtime. Always statically determine what type you are going to
+ call, and call its :c:member:`~PyTypeObject.tp_new` directly, or via
+ ``type->tp_base->tp_new``. If you do not do this, Python subclasses of your
+ type that also inherit from other Python-defined classes may not work correctly.
+ (Specifically, you may not be able to create instances of such subclasses
+ without getting a :exc:`TypeError`.)
+
+We also define an initialization function which accepts arguments to provide
+initial values for our instance::
+
+ static int
+ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+ {
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_XDECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_XDECREF(tmp);
+ }
+ return 0;
+ }
+
+by filling the :c:member:`~PyTypeObject.tp_init` slot. ::
+
+ .tp_init = (initproc) Custom_init,
+
+The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the
+:meth:`__init__` method. It is used to initialize an object after it's
+created. Initializers always accept positional and keyword arguments,
+and they should return either ``0`` on success or ``-1`` on error.
+
+Unlike the ``tp_new`` handler, there is no guarantee that ``tp_init``
+is called at all (for example, the :mod:`pickle` module by default
+doesn't call :meth:`__init__` on unpickled instances). It can also be
+called multiple times. Anyone can call the :meth:`__init__` method on
+our objects. For this reason, we have to be extra careful when assigning
+the new attribute values. We might be tempted, for example to assign the
+``first`` member like this::
+
+ if (first) {
+ Py_XDECREF(self->first);
+ Py_INCREF(first);
+ self->first = first;
+ }
+
+But this would be risky. Our type doesn't restrict the type of the
+``first`` member, so it could be any kind of object. It could have a
+destructor that causes code to be executed that tries to access the
+``first`` member; or that destructor could release the
+:term:`Global interpreter Lock` and let arbitrary code run in other
+threads that accesses and modifies our object.
+
+To be paranoid and protect ourselves against this possibility, we almost
+always reassign members before decrementing their reference counts. When
+don't we have to do this?
+
+* when we absolutely know that the reference count is greater than 1;
+
+* when we know that deallocation of the object [#]_ will neither release
+ the :term:`GIL` nor cause any calls back into our type's code;
+
+* when decrementing a reference count in a :c:member:`~PyTypeObject.tp_dealloc`
+ handler on a type which doesn't support cyclic garbage collection [#]_.
+
+We want to expose our instance variables as attributes. There are a
+number of ways to do that. The simplest way is to define member definitions::
+
+ static PyMemberDef Custom_members[] = {
+ {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0,
+ "first name"},
+ {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0,
+ "last name"},
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+ };
+
+and put the definitions in the :c:member:`~PyTypeObject.tp_members` slot::
+
+ .tp_members = Custom_members,
+
+Each member definition has a member name, type, offset, access flags and
+documentation string. See the :ref:`Generic-Attribute-Management` section
+below for details.
+
+A disadvantage of this approach is that it doesn't provide a way to restrict the
+types of objects that can be assigned to the Python attributes. We expect the
+first and last names to be strings, but any Python objects can be assigned.
+Further, the attributes can be deleted, setting the C pointers to ``NULL``. Even
+though we can make sure the members are initialized to non-``NULL`` values, the
+members can be set to ``NULL`` if the attributes are deleted.
+
+We define a single method, :meth:`Custom.name()`, that outputs the objects name as the
+concatenation of the first and last names. ::
+
+ static PyObject *
+ Custom_name(CustomObject *self)
+ {
+ if (self->first == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "first");
+ return NULL;
+ }
+ if (self->last == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "last");
+ return NULL;
+ }
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+ }
+
+The method is implemented as a C function that takes a :class:`Custom` (or
+:class:`Custom` subclass) instance as the first argument. Methods always take an
+instance as the first argument. Methods often take positional and keyword
+arguments as well, but in this case we don't take any and don't need to accept
+a positional argument tuple or keyword argument dictionary. This method is
+equivalent to the Python method:
+
+.. code-block:: python
+
+ def name(self):
+ return "%s %s" % (self.first, self.last)
+
+Note that we have to check for the possibility that our :attr:`first` and
+:attr:`last` members are ``NULL``. This is because they can be deleted, in which
+case they are set to ``NULL``. It would be better to prevent deletion of these
+attributes and to restrict the attribute values to be strings. We'll see how to
+do that in the next section.
+
+Now that we've defined the method, we need to create an array of method
+definitions::
+
+ static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+ };
+
+(note that we used the :const:`METH_NOARGS` flag to indicate that the method
+is expecting no arguments other than *self*)
+
+and assign it to the :c:member:`~PyTypeObject.tp_methods` slot::
+
+ .tp_methods = Custom_methods,
+
+Finally, we'll make our type usable as a base class for subclassing. We've
+written our methods carefully so far so that they don't make any assumptions
+about the type of the object being created or used, so all we need to do is
+to add the :const:`Py_TPFLAGS_BASETYPE` to our class flag definition::
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+We rename :c:func:`PyInit_custom` to :c:func:`PyInit_custom2`, update the
+module name in the :c:type:`PyModuleDef` struct, and update the full class
+name in the :c:type:`PyTypeObject` struct.
+
+Finally, we update our :file:`setup.py` file to build the new module:
+
+.. code-block:: python
+
+ from distutils.core import setup, Extension
+ setup(name="custom", version="1.0",
+ ext_modules=[
+ Extension("custom", ["custom.c"]),
+ Extension("custom2", ["custom2.c"]),
+ ])
+
+
+Providing finer control over data attributes
+============================================
+
+In this section, we'll provide finer control over how the :attr:`first` and
+:attr:`last` attributes are set in the :class:`Custom` example. In the previous
+version of our module, the instance variables :attr:`first` and :attr:`last`
+could be set to non-string values or even deleted. We want to make sure that
+these attributes always contain strings.
+
+.. literalinclude:: ../includes/custom3.c
+
+
+To provide greater control, over the :attr:`first` and :attr:`last` attributes,
+we'll use custom getter and setter functions. Here are the functions for
+getting and setting the :attr:`first` attribute::
+
+ static PyObject *
+ Custom_getfirst(CustomObject *self, void *closure)
+ {
+ Py_INCREF(self->first);
+ return self->first;
+ }
+
+ static int
+ Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
+ {
+ PyObject *tmp;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a string");
+ return -1;
+ }
+ tmp = self->first;
+ Py_INCREF(value);
+ self->first = value;
+ Py_DECREF(tmp);
+ return 0;
+ }
+
+The getter function is passed a :class:`Custom` object and a "closure", which is
+a void pointer. In this case, the closure is ignored. (The closure supports an
+advanced usage in which definition data is passed to the getter and setter. This
+could, for example, be used to allow a single set of getter and setter functions
+that decide the attribute to get or set based on data in the closure.)
+
+The setter function is passed the :class:`Custom` object, the new value, and the
+closure. The new value may be ``NULL``, in which case the attribute is being
+deleted. In our setter, we raise an error if the attribute is deleted or if its
+new value is not a string.
+
+We create an array of :c:type:`PyGetSetDef` structures::
+
+ static PyGetSetDef Custom_getsetters[] = {
+ {"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
+ "first name", NULL},
+ {"last", (getter) Custom_getlast, (setter) Custom_setlast,
+ "last name", NULL},
+ {NULL} /* Sentinel */
+ };
+
+and register it in the :c:member:`~PyTypeObject.tp_getset` slot::
+
+ .tp_getset = Custom_getsetters,
+
+The last item in a :c:type:`PyGetSetDef` structure is the "closure" mentioned
+above. In this case, we aren't using a closure, so we just pass ``NULL``.
+
+We also remove the member definitions for these attributes::
+
+ static PyMemberDef Custom_members[] = {
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+ };
+
+We also need to update the :c:member:`~PyTypeObject.tp_init` handler to only
+allow strings [#]_ to be passed::
+
+ static int
+ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+ {
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_DECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_DECREF(tmp);
+ }
+ return 0;
+ }
+
+With these changes, we can assure that the ``first`` and ``last`` members are
+never ``NULL`` so we can remove checks for ``NULL`` values in almost all cases.
+This means that most of the :c:func:`Py_XDECREF` calls can be converted to
+:c:func:`Py_DECREF` calls. The only place we can't change these calls is in
+the ``tp_dealloc`` implementation, where there is the possibility that the
+initialization of these members failed in ``tp_new``.
+
+We also rename the module initialization function and module name in the
+initialization function, as we did before, and we add an extra definition to the
+:file:`setup.py` file.
+
+
+Supporting cyclic garbage collection
+====================================
+
+Python has a :term:`cyclic garbage collector (GC) ` that
+can identify unneeded objects even when their reference counts are not zero.
+This can happen when objects are involved in cycles. For example, consider:
+
+.. code-block:: pycon
+
+ >>> l = []
+ >>> l.append(l)
+ >>> del l
+
+In this example, we create a list that contains itself. When we delete it, it
+still has a reference from itself. Its reference count doesn't drop to zero.
+Fortunately, Python's cyclic garbage collector will eventually figure out that
+the list is garbage and free it.
+
+In the second version of the :class:`Custom` example, we allowed any kind of
+object to be stored in the :attr:`first` or :attr:`last` attributes [#]_.
+Besides, in the second and third versions, we allowed subclassing
+:class:`Custom`, and subclasses may add arbitrary attributes. For any of
+those two reasons, :class:`Custom` objects can participate in cycles:
+
+.. code-block:: pycon
+
+ >>> import custom3
+ >>> class Derived(custom3.Custom): pass
+ ...
+ >>> n = Derived()
+ >>> n.some_attribute = n
+
+To allow a :class:`Custom` instance participating in a reference cycle to
+be properly detected and collected by the cyclic GC, our :class:`Custom` type
+needs to fill two additional slots and to enable a flag that enables these slots:
+
+.. literalinclude:: ../includes/custom4.c
+
+
+First, the traversal method lets the cyclic GC know about subobjects that could
+participate in cycles::
+
+ static int
+ Custom_traverse(CustomObject *self, visitproc visit, void *arg)
+ {
+ int vret;
+ if (self->first) {
+ vret = visit(self->first, arg);
+ if (vret != 0)
+ return vret;
+ }
+ if (self->last) {
+ vret = visit(self->last, arg);
+ if (vret != 0)
+ return vret;
+ }
+ return 0;
+ }
+
+For each subobject that can participate in cycles, we need to call the
+:c:func:`visit` function, which is passed to the traversal method. The
+:c:func:`visit` function takes as arguments the subobject and the extra argument
+*arg* passed to the traversal method. It returns an integer value that must be
+returned if it is non-zero.
+
+Python provides a :c:func:`Py_VISIT` macro that automates calling visit
+functions. With :c:func:`Py_VISIT`, we can minimize the amount of boilerplate
+in ``Custom_traverse``::
+
+ static int
+ Custom_traverse(CustomObject *self, visitproc visit, void *arg)
+ {
+ Py_VISIT(self->first);
+ Py_VISIT(self->last);
+ return 0;
+ }
+
+.. note::
+ The :c:member:`~PyTypeObject.tp_traverse` implementation must name its
+ arguments exactly *visit* and *arg* in order to use :c:func:`Py_VISIT`.
+
+Second, we need to provide a method for clearing any subobjects that can
+participate in cycles::
+
+ static int
+ Custom_clear(CustomObject *self)
+ {
+ Py_CLEAR(self->first);
+ Py_CLEAR(self->last);
+ return 0;
+ }
+
+Notice the use of the :c:func:`Py_CLEAR` macro. It is the recommended and safe
+way to clear data attributes of arbitrary types while decrementing
+their reference counts. If you were to call :c:func:`Py_XDECREF` instead
+on the attribute before setting it to ``NULL``, there is a possibility
+that the attribute's destructor would call back into code that reads the
+attribute again (*especially* if there is a reference cycle).
+
+.. note::
+ You could emulate :c:func:`Py_CLEAR` by writing::
+
+ PyObject *tmp;
+ tmp = self->first;
+ self->first = NULL;
+ Py_XDECREF(tmp);
+
+ Nevertheless, it is much easier and less error-prone to always
+ use :c:func:`Py_CLEAR` when deleting an attribute. Don't
+ try to micro-optimize at the expense of robustness!
+
+The deallocator ``Custom_dealloc`` may call arbitrary code when clearing
+attributes. It means the circular GC can be triggered inside the function.
+Since the GC assumes reference count is not zero, we need to untrack the object
+from the GC by calling :c:func:`PyObject_GC_UnTrack` before clearing members.
+Here is our reimplemented deallocator using :c:func:`PyObject_GC_UnTrack`
+and ``Custom_clear``::
+
+ static void
+ Custom_dealloc(CustomObject *self)
+ {
+ PyObject_GC_UnTrack(self);
+ Custom_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+ }
+
+Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+
+That's pretty much it. If we had written custom :c:member:`~PyTypeObject.tp_alloc` or
+:c:member:`~PyTypeObject.tp_free` handlers, we'd need to modify them for cyclic
+garbage collection. Most extensions will use the versions automatically provided.
+
+
+Subclassing other types
+=======================
+
+It is possible to create new extension types that are derived from existing
+types. It is easiest to inherit from the built in types, since an extension can
+easily use the :c:type:`PyTypeObject` it needs. It can be difficult to share
+these :c:type:`PyTypeObject` structures between extension modules.
+
+In this example we will create a :class:`SubList` type that inherits from the
+built-in :class:`list` type. The new type will be completely compatible with
+regular lists, but will have an additional :meth:`increment` method that
+increases an internal counter:
+
+.. code-block:: pycon
+
+ >>> import sublist
+ >>> s = sublist.SubList(range(3))
+ >>> s.extend(s)
+ >>> print(len(s))
+ 6
+ >>> print(s.increment())
+ 1
+ >>> print(s.increment())
+ 2
+
+.. literalinclude:: ../includes/sublist.c
+
+
+As you can see, the source code closely resembles the :class:`Custom` examples in
+previous sections. We will break down the main differences between them. ::
+
+ typedef struct {
+ PyListObject list;
+ int state;
+ } SubListObject;
+
+The primary difference for derived type objects is that the base type's
+object structure must be the first value. The base type will already include
+the :c:func:`PyObject_HEAD` at the beginning of its structure.
+
+When a Python object is a :class:`SubList` instance, its ``PyObject *`` pointer
+can be safely cast to both ``PyListObject *`` and ``SubListObject *``::
+
+ static int
+ SubList_init(SubListObject *self, PyObject *args, PyObject *kwds)
+ {
+ if (PyList_Type.tp_init((PyObject *) self, args, kwds) < 0)
+ return -1;
+ self->state = 0;
+ return 0;
+ }
+
+We see above how to call through to the :attr:`__init__` method of the base
+type.
+
+This pattern is important when writing a type with custom
+:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_dealloc`
+members. The :c:member:`~PyTypeObject.tp_new` handler should not actually
+create the memory for the object with its :c:member:`~PyTypeObject.tp_alloc`,
+but let the base class handle it by calling its own :c:member:`~PyTypeObject.tp_new`.
+
+The :c:type:`PyTypeObject` struct supports a :c:member:`~PyTypeObject.tp_base`
+specifying the type's concrete base class. Due to cross-platform compiler
+issues, you can't fill that field directly with a reference to
+:c:type:`PyList_Type`; it should be done later in the module initialization
+function::
+
+ PyMODINIT_FUNC
+ PyInit_sublist(void)
+ {
+ PyObject* m;
+ SubListType.tp_base = &PyList_Type;
+ if (PyType_Ready(&SubListType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&sublistmodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&SubListType);
+ if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
+ Py_DECREF(&SubListType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
+ return m;
+ }
+
+Before calling :c:func:`PyType_Ready`, the type structure must have the
+:c:member:`~PyTypeObject.tp_base` slot filled in. When we are deriving an
+existing type, it is not necessary to fill out the :c:member:`~PyTypeObject.tp_alloc`
+slot with :c:func:`PyType_GenericNew` -- the allocation function from the base
+type will be inherited.
+
+After that, calling :c:func:`PyType_Ready` and adding the type object to the
+module is the same as with the basic :class:`Custom` examples.
+
+
+.. rubric:: Footnotes
+
+.. [#] This is true when we know that the object is a basic type, like a string or a
+ float.
+
+.. [#] We relied on this in the :c:member:`~PyTypeObject.tp_dealloc` handler
+ in this example, because our type doesn't support garbage collection.
+
+.. [#] We now know that the first and last members are strings, so perhaps we
+ could be less careful about decrementing their reference counts, however,
+ we accept instances of string subclasses. Even though deallocating normal
+ strings won't call back into our objects, we can't guarantee that deallocating
+ an instance of a string subclass won't call back into our objects.
+
+.. [#] Also, even with our attributes restricted to strings instances, the user
+ could pass arbitrary :class:`str` subclasses and therefore still create
+ reference cycles.
diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst
index 2e56fbc2f425ec..e2d63a0323da66 100644
--- a/Doc/faq/design.rst
+++ b/Doc/faq/design.rst
@@ -2,6 +2,11 @@
Design and History FAQ
======================
+.. only:: html
+
+ .. contents::
+
+
Why does Python use indentation for grouping of statements?
-----------------------------------------------------------
@@ -210,24 +215,25 @@ objects using the ``for`` statement. For example, :term:`file objects
Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?
----------------------------------------------------------------------------------------------------------------
-The major reason is history. Functions were used for those operations that were
-generic for a group of types and which were intended to work even for objects
-that didn't have methods at all (e.g. tuples). It is also convenient to have a
-function that can readily be applied to an amorphous collection of objects when
-you use the functional features of Python (``map()``, ``zip()`` et al).
+As Guido said:
-In fact, implementing ``len()``, ``max()``, ``min()`` as a built-in function is
-actually less code than implementing them as methods for each type. One can
-quibble about individual cases but it's a part of Python, and it's too late to
-make such fundamental changes now. The functions have to remain to avoid massive
-code breakage.
+ (a) For some operations, prefix notation just reads better than
+ postfix -- prefix (and infix!) operations have a long tradition in
+ mathematics which likes notations where the visuals help the
+ mathematician thinking about a problem. Compare the easy with which we
+ rewrite a formula like x*(a+b) into x*a + x*b to the clumsiness of
+ doing the same thing using a raw OO notation.
-.. XXX talk about protocols?
+ (b) When I read code that says len(x) I *know* that it is asking for
+ the length of something. This tells me two things: the result is an
+ integer, and the argument is some kind of container. To the contrary,
+ when I read x.len(), I have to already know that x is some kind of
+ container implementing an interface or inheriting from a class that
+ has a standard len(). Witness the confusion we occasionally have when
+ a class that is not implementing a mapping has a get() or keys()
+ method, or something that isn't a file has a write() method.
-.. note::
-
- For string operations, Python has moved from external functions (the
- ``string`` module) to methods. However, ``len()`` is still a function.
+ -- https://mail.python.org/pipermail/python-3000/2006-November/004643.html
Why is join() a string method instead of a list or tuple method?
@@ -343,7 +349,7 @@ each Python stack frame. Also, extensions can call back into Python at almost
random moments. Therefore, a complete threads implementation requires thread
support for C.
-Answer 2: Fortunately, there is `Stackless Python `_,
+Answer 2: Fortunately, there is `Stackless Python `_,
which has a completely redesigned interpreter loop that avoids the C stack.
@@ -465,10 +471,10 @@ you can always change a list's elements. Only immutable elements can be used as
dictionary keys, and hence only tuples and not lists can be used as keys.
-How are lists implemented?
---------------------------
+How are lists implemented in CPython?
+-------------------------------------
-Python's lists are really variable-length arrays, not Lisp-style linked lists.
+CPython's lists are really variable-length arrays, not Lisp-style linked lists.
The implementation uses a contiguous array of references to other objects, and
keeps a pointer to this array and the array's length in a list head structure.
@@ -481,10 +487,10 @@ when the array must be grown, some extra space is allocated so the next few
times don't require an actual resize.
-How are dictionaries implemented?
----------------------------------
+How are dictionaries implemented in CPython?
+--------------------------------------------
-Python's dictionaries are implemented as resizable hash tables. Compared to
+CPython's dictionaries are implemented as resizable hash tables. Compared to
B-trees, this gives better performance for lookup (the most common operation by
far) under most circumstances, and the implementation is simpler.
@@ -495,11 +501,7 @@ on the key and a per-process seed; for example, "Python" could hash to
to 1142331976. The hash code is then used to calculate a location in an
internal array where the value will be stored. Assuming that you're storing
keys that all have different hash values, this means that dictionaries take
-constant time -- O(1), in computer science notation -- to retrieve a key. It
-also means that no sorted order of the keys is maintained, and traversing the
-array as the ``.keys()`` and ``.items()`` do will output the dictionary's
-content in some arbitrary jumbled order that can change with every invocation of
-a program.
+constant time -- O(1), in Big-O notation -- to retrieve a key.
Why must dictionary keys be immutable?
@@ -526,7 +528,7 @@ Some unacceptable solutions that have been proposed:
mydict = {[1, 2]: '12'}
print(mydict[[1, 2]])
- would raise a KeyError exception because the id of the ``[1, 2]`` used in the
+ would raise a :exc:`KeyError` exception because the id of the ``[1, 2]`` used in the
second line differs from that in the first line. In other words, dictionary
keys should be compared using ``==``, not using :keyword:`is`.
diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst
index 88996e48035b24..aecb56eaa4fd2f 100644
--- a/Doc/faq/extending.rst
+++ b/Doc/faq/extending.rst
@@ -62,8 +62,8 @@ How can I execute arbitrary Python statements from C?
The highest-level function to do this is :c:func:`PyRun_SimpleString` which takes
a single string argument to be executed in the context of the module
-``__main__`` and returns 0 for success and -1 when an exception occurred
-(including ``SyntaxError``). If you want more control, use
+``__main__`` and returns ``0`` for success and ``-1`` when an exception occurred
+(including :exc:`SyntaxError`). If you want more control, use
:c:func:`PyRun_String`; see the source for :c:func:`PyRun_SimpleString` in
``Python/pythonrun.c``.
@@ -89,7 +89,7 @@ For bytes, :c:func:`PyBytes_Size` returns its length and
length. Note that Python bytes objects may contain null bytes so C's
:c:func:`strlen` should not be used.
-To test the type of an object, first make sure it isn't *NULL*, and then use
+To test the type of an object, first make sure it isn't ``NULL``, and then use
:c:func:`PyBytes_Check`, :c:func:`PyTuple_Check`, :c:func:`PyList_Check`, etc.
There is also a high-level API to Python objects which is provided by the
@@ -277,9 +277,10 @@ However sometimes you have to run the embedded Python interpreter in the same
thread as your rest application and you can't allow the
:c:func:`PyRun_InteractiveLoop` to stop while waiting for user input. The one
solution then is to call :c:func:`PyParser_ParseString` and test for ``e.error``
-equal to ``E_EOF``, which means the input is incomplete). Here's a sample code
+equal to ``E_EOF``, which means the input is incomplete. Here's a sample code
fragment, untested, inspired by code from Alex Farber::
+ #define PY_SSIZE_T_CLEAN
#include
#include
#include
@@ -318,6 +319,7 @@ complete example using the GNU readline library (you may want to ignore
#include
#include
+ #define PY_SSIZE_T_CLEAN
#include
#include
#include
diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst
index 0d1cb198da87d8..3ef553e8acb43c 100644
--- a/Doc/faq/general.rst
+++ b/Doc/faq/general.rst
@@ -117,7 +117,7 @@ programming), software engineering (unit testing, logging, profiling, parsing
Python code), and operating system interfaces (system calls, filesystems, TCP/IP
sockets). Look at the table of contents for :ref:`library-index` to get an idea
of what's available. A wide variety of third-party extensions are also
-available. Consult `the Python Package Index `_ to
+available. Consult `the Python Package Index `_ to
find packages of interest to you.
@@ -268,14 +268,8 @@ Python references; or perhaps search for "Python" and "language".
Where in the world is www.python.org located?
---------------------------------------------
-The Python project's infrastructure is located all over the world.
-`www.python.org `_ is graciously hosted by `Rackspace
-`_, with CDN caching provided by `Fastly
-`_. `Upfront Systems
-`_ hosts `bugs.python.org
-`_. Many other Python services like `the Wiki
-`_ are hosted by `Oregon State
-University Open Source Lab `_.
+The Python project's infrastructure is located all over the world and is managed
+by the Python Infrastructure Team. Details `here `__.
Why is it called Python?
@@ -306,18 +300,16 @@ usually around 18 months between major releases.
The developers issue "bugfix" releases of older versions, so the stability of
existing releases gradually improves. Bugfix releases, indicated by a third
-component of the version number (e.g. 2.5.3, 2.6.2), are managed for stability;
+component of the version number (e.g. 3.5.3, 3.6.2), are managed for stability;
only fixes for known problems are included in a bugfix release, and it's
guaranteed that interfaces will remain the same throughout a series of bugfix
releases.
The latest stable releases can always be found on the `Python download page
-`_. There are two recommended production-ready
-versions at this point in time, because at the moment there are two branches of
-stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since
-currently there is more third party software available for Python 2 than for
-Python 3. Python 2 code will generally not run unchanged in Python 3.
-
+`_. There are two production-ready versions
+of Python: 2.x and 3.x. The recommended version is 3.x, which is supported by
+most widely used libraries. Although 2.x is still widely used, `it will not
+be maintained after January 1, 2020 `_.
How many people are using Python?
---------------------------------
diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst
index 4f9979bf55ed3a..781da467d18013 100644
--- a/Doc/faq/gui.rst
+++ b/Doc/faq/gui.rst
@@ -104,7 +104,7 @@ What platform-specific GUI toolkits exist for Python?
========================================================
By installing the `PyObjc Objective-C bridge
-`_, Python programs can use Mac OS X's
+`_, Python programs can use Mac OS X's
Cocoa libraries.
:ref:`Pythonwin ` by Mark Hammond includes an interface to the
diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst
index f84feadd780234..ab92a879a88516 100644
--- a/Doc/faq/library.rst
+++ b/Doc/faq/library.rst
@@ -19,7 +19,7 @@ standard library module. (Eventually you'll learn what's in the standard
library and will be able to skip this step.)
For third-party packages, search the `Python Package Index
-`_ or try `Google `_ or
+`_ or try `Google `_ or
another Web search engine. Searching for "Python" plus a keyword or two for
your topic of interest will usually find something helpful.
@@ -74,7 +74,9 @@ interpreter.
Occasionally, a user's environment is so full that the :program:`/usr/bin/env`
program fails; or there's no env program at all. In that case, you can try the
-following hack (due to Alex Rezinsky)::
+following hack (due to Alex Rezinsky):
+
+.. code-block:: sh
#! /bin/sh
""":"
@@ -609,7 +611,7 @@ use ``p.read(n)``.
"expect" library. A Python extension that interfaces to expect is called
"expy" and available from http://expectpy.sourceforge.net. A pure Python
solution that works like expect is `pexpect
- `_.
+ `_.
How do I access the serial (RS232) port?
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index 1a2f582a31ad17..604c8ff521e89d 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -16,6 +16,9 @@ Is there a source code level debugger with breakpoints, single-stepping, etc.?
Yes.
+Several debuggers for Python are described below, and the built-in function
+:func:`breakpoint` allows you to drop into any of them.
+
The pdb module is a simple but adequate console-mode debugger for Python. It is
part of the standard Python library, and is :mod:`documented in the Library
Reference Manual `. You can also write your own debugger by using the code
@@ -71,6 +74,11 @@ length, whether variable names are well-formed according to your coding
standard, whether declared interfaces are fully implemented, and more.
https://docs.pylint.org/ provides a full list of Pylint's features.
+Static type checkers such as `Mypy `_,
+`Pyre `_, and
+`Pytype `_ can check type hints in Python
+source code.
+
How can I create a stand-alone binary from a Python script?
-----------------------------------------------------------
@@ -371,8 +379,8 @@ compute, a common technique is to cache the parameters and the resulting value
of each call to the function, and return the cached value if the same value is
requested again. This is called "memoizing", and can be implemented like this::
- # Callers will never provide a third parameter for this function.
- def expensive(arg1, arg2, _cache={}):
+ # Callers can only provide two parameters and optionally pass _cache by keyword
+ def expensive(arg1, arg2, *, _cache={}):
if (arg1, arg2) in _cache:
return _cache[(arg1, arg2)]
@@ -651,7 +659,7 @@ How can my code discover the name of an object?
-----------------------------------------------
Generally speaking, it can't, because objects don't really have names.
-Essentially, assignment always binds a name to a value; The same is true of
+Essentially, assignment always binds a name to a value; the same is true of
``def`` and ``class`` statements, but in that case the value is a
callable. Consider the following code::
@@ -733,7 +741,7 @@ Is it possible to write obfuscated one-liners in Python?
--------------------------------------------------------
Yes. Usually this is done by nesting :keyword:`lambda` within
-:keyword:`lambda`. See the following three examples, due to Ulf Bartelt::
+:keyword:`!lambda`. See the following three examples, due to Ulf Bartelt::
from functools import reduce
@@ -762,6 +770,41 @@ Yes. Usually this is done by nesting :keyword:`lambda` within
Don't try this at home, kids!
+.. _faq-positional-only-arguments:
+
+What does the slash(/) in the parameter list of a function mean?
+----------------------------------------------------------------
+
+A slash in the argument list of a function denotes that the parameters prior to
+it are positional-only. Positional-only parameters are the ones without an
+externally-usable name. Upon calling a function that accepts positional-only
+parameters, arguments are mapped to parameters based solely on their position.
+For example, :func:`pow` is a function that accepts positional-only parameters.
+Its documentation looks like this::
+
+ >>> help(pow)
+ Help on built-in function pow in module builtins:
+
+ pow(x, y, z=None, /)
+ Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
+
+ Some types, such as ints, are able to use a more efficient algorithm when
+ invoked using the three argument form.
+
+The slash at the end of the parameter list means that all three parameters are
+positional-only. Thus, calling :func:`pow` with keyword aguments would lead to
+an error::
+
+ >>> pow(x=3, y=4)
+ Traceback (most recent call last):
+ File "", line 1, in
+ TypeError: pow() takes no keyword arguments
+
+Note that as of this writing this is only documentational and no valid syntax
+in Python, although there is :pep:`570`, which proposes a syntax for
+position-only parameters in Python.
+
+
Numbers and strings
===================
@@ -983,7 +1026,7 @@ That's a tough one, in general. First, here are a list of things to
remember before diving further:
* Performance characteristics vary across Python implementations. This FAQ
- focusses on :term:`CPython`.
+ focuses on :term:`CPython`.
* Behaviour can vary across operating systems, especially when talking about
I/O or multi-threading.
* You should always find the hot spots in your program *before* attempting to
@@ -1312,14 +1355,6 @@ The ``__iadd__`` succeeds, and thus the list is extended, but even though
that final assignment still results in an error, because tuples are immutable.
-Dictionaries
-============
-
-How can I get a dictionary to store and display its keys in a consistent order?
--------------------------------------------------------------------------------
-
-Use :class:`collections.OrderedDict`.
-
I want to do a complicated sort: can you do a Schwartzian Transform in Python?
------------------------------------------------------------------------------
@@ -1466,8 +1501,8 @@ to uppercase::
Here the ``UpperOut`` class redefines the ``write()`` method to convert the
argument string to uppercase before calling the underlying
-``self.__outfile.write()`` method. All other methods are delegated to the
-underlying ``self.__outfile`` object. The delegation is accomplished via the
+``self._outfile.write()`` method. All other methods are delegated to the
+underlying ``self._outfile`` object. The delegation is accomplished via the
``__getattr__`` method; consult :ref:`the language reference `
for more information about controlling attribute access.
diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst
index d703f2862221a6..a92ec1b52ad4fe 100644
--- a/Doc/faq/windows.rst
+++ b/Doc/faq/windows.rst
@@ -1,5 +1,7 @@
:tocdepth: 2
+.. highlightlang:: none
+
.. _windows-faq:
=====================
@@ -13,6 +15,8 @@ Python on Windows FAQ
.. XXX need review for Python 3.
XXX need review for Windows Vista/Seven?
+.. _faq-run-program-under-windows:
+
How do I run a Python program under Windows?
--------------------------------------------
@@ -21,30 +25,21 @@ This is not necessarily a straightforward question. If you are already familiar
with running programs from the Windows command line then everything will seem
obvious; otherwise, you might need a little more guidance.
-.. sidebar:: |Python Development on XP|_
- :subtitle: `Python Development on XP`_
-
- This series of screencasts aims to get you up and running with Python on
- Windows XP. The knowledge is distilled into 1.5 hours and will get you up
- and running with the right Python distribution, coding in your choice of IDE,
- and debugging and writing solid code with unit-tests.
-
-.. |Python Development on XP| image:: python-video-icon.png
-.. _`Python Development on XP`:
- http://showmedo.com/videotutorials/series?name=pythonOzsvaldPyNewbieSeries
-
Unless you use some sort of integrated development environment, you will end up
*typing* Windows commands into what is variously referred to as a "DOS window"
or "Command prompt window". Usually you can create such a window from your
-Start menu; under Windows 7 the menu selection is :menuselection:`Start -->
-Programs --> Accessories --> Command Prompt`. You should be able to recognize
+search bar by searching for ``cmd``. You should be able to recognize
when you have started such a window because you will see a Windows "command
-prompt", which usually looks like this::
+prompt", which usually looks like this:
+
+.. code-block:: doscon
C:\>
The letter may be different, and there might be other things after it, so you
-might just as easily see something like::
+might just as easily see something like:
+
+.. code-block:: doscon
D:\YourName\Projects\Python>
@@ -58,22 +53,28 @@ compiles it into bytecodes, and then executes the bytecodes to run your
program. So, how do you arrange for the interpreter to handle your Python?
First, you need to make sure that your command window recognises the word
-"python" as an instruction to start the interpreter. If you have opened a
-command window, you should try entering the command ``python`` and hitting
-return.::
+"py" as an instruction to start the interpreter. If you have opened a
+command window, you should try entering the command ``py`` and hitting
+return:
+
+.. code-block:: doscon
- C:\Users\YourName> python
+ C:\Users\YourName> py
-You should then see something like::
+You should then see something like:
- Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32
+.. code-block:: pycon
+
+ Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
You have started the interpreter in "interactive mode". That means you can enter
Python statements or expressions interactively and have them executed or
evaluated while you wait. This is one of Python's strongest features. Check it
-by entering a few expressions of your choice and seeing the results::
+by entering a few expressions of your choice and seeing the results:
+
+.. code-block:: pycon
>>> print("Hello")
Hello
@@ -81,64 +82,33 @@ by entering a few expressions of your choice and seeing the results::
'HelloHelloHello'
Many people use the interactive mode as a convenient yet highly programmable
-calculator. When you want to end your interactive Python session, hold the :kbd:`Ctrl`
-key down while you enter a :kbd:`Z`, then hit the ":kbd:`Enter`" key to get back to your
-Windows command prompt.
+calculator. When you want to end your interactive Python session,
+call the :func:`exit` function or hold the :kbd:`Ctrl` key down
+while you enter a :kbd:`Z`, then hit the ":kbd:`Enter`" key to get
+back to your Windows command prompt.
You may also find that you have a Start-menu entry such as :menuselection:`Start
---> Programs --> Python 3.3 --> Python (command line)` that results in you
+--> Programs --> Python 3.x --> Python (command line)` that results in you
seeing the ``>>>`` prompt in a new window. If so, the window will disappear
-after you enter the :kbd:`Ctrl-Z` character; Windows is running a single "python"
+after you call the :func:`exit` function or enter the :kbd:`Ctrl-Z`
+character; Windows is running a single "python"
command in the window, and closes it when you terminate the interpreter.
-If the ``python`` command, instead of displaying the interpreter prompt ``>>>``,
-gives you a message like::
-
- 'python' is not recognized as an internal or external command, operable program or batch file.
-
-.. sidebar:: |Adding Python to DOS Path|_
- :subtitle: `Adding Python to DOS Path`_
-
- Python is not added to the DOS path by default. This screencast will walk
- you through the steps to add the correct entry to the `System Path`, allowing
- Python to be executed from the command-line by all users.
-
-.. |Adding Python to DOS Path| image:: python-video-icon.png
-.. _`Adding Python to DOS Path`:
- http://showmedo.com/videotutorials/video?name=960000&fromSeriesID=96
-
-
-or::
+Now that we know the ``py`` command is recognized, you can give your
+Python script to it. You'll have to give either an absolute or a
+relative path to the Python script. Let's say your Python script is
+located in your desktop and is named ``hello.py``, and your command
+prompt is nicely opened in your home directory so you're seeing something
+similar to::
- Bad command or filename
+ C:\Users\YourName>
-then you need to make sure that your computer knows where to find the Python
-interpreter. To do this you will have to modify a setting called PATH, which is
-a list of directories where Windows will look for programs.
+So now you'll ask the ``py`` command to give your script to Python by
+typing ``py`` followed by your script path::
-You should arrange for Python's installation directory to be added to the PATH
-of every command window as it starts. If you installed Python fairly recently
-then the command ::
- dir C:\py*
-
-will probably tell you where it is installed; the usual location is something
-like ``C:\Python33``. Otherwise you will be reduced to a search of your whole
-disk ... use :menuselection:`Tools --> Find` or hit the :guilabel:`Search`
-button and look for "python.exe". Supposing you discover that Python is
-installed in the ``C:\Python33`` directory (the default at the time of writing),
-you should make sure that entering the command ::
-
- c:\Python33\python
-
-starts up the interpreter as above (and don't forget you'll need a ":kbd:`Ctrl-Z`" and
-an ":kbd:`Enter`" to get out of it). Once you have verified the directory, you can
-add it to the system path to make it easier to start Python by just running
-the ``python`` command. This is currently an option in the installer as of
-CPython 3.3.
-
-More information about environment variables can be found on the
-:ref:`Using Python on Windows ` page.
+ C:\Users\YourName> py Desktop\hello.py
+ hello
How do I make Python scripts executable?
----------------------------------------
@@ -312,34 +282,3 @@ How do I check for a keypress without blocking?
Use the msvcrt module. This is a standard Windows-specific extension module.
It defines a function ``kbhit()`` which checks whether a keyboard hit is
present, and ``getch()`` which gets one character without echoing it.
-
-
-How do I emulate os.kill() in Windows?
---------------------------------------
-
-Prior to Python 2.7 and 3.2, to terminate a process, you can use :mod:`ctypes`::
-
- import ctypes
-
- def kill(pid):
- """kill function for Win32"""
- kernel32 = ctypes.windll.kernel32
- handle = kernel32.OpenProcess(1, 0, pid)
- return (0 != kernel32.TerminateProcess(handle, 0))
-
-In 2.7 and 3.2, :func:`os.kill` is implemented similar to the above function,
-with the additional feature of being able to send :kbd:`Ctrl+C` and :kbd:`Ctrl+Break`
-to console subprocesses which are designed to handle those signals. See
-:func:`os.kill` for further details.
-
-How do I extract the downloaded documentation on Windows?
----------------------------------------------------------
-
-Sometimes, when you download the documentation package to a Windows machine
-using a web browser, the file extension of the saved file ends up being .EXE.
-This is a mistake; the extension should be .TGZ.
-
-Simply rename the downloaded file to have the .TGZ extension, and WinZip will be
-able to handle it. (If your copy of WinZip doesn't, get a newer one from
-https://www.winzip.com.)
-
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index dcfe086b38b12f..ed588612aeabed 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -13,9 +13,10 @@ Glossary
examples which can be executed interactively in the interpreter.
``...``
- The default Python prompt of the interactive shell when entering code for
- an indented code block or within a pair of matching left and right
- delimiters (parentheses, square brackets or curly braces).
+ The default Python prompt of the interactive shell when entering the
+ code for an indented code block, when within a pair of matching left and
+ right delimiters (parentheses, square brackets, curly braces or triple
+ quotes), or after specifying a decorator.
2to3
A tool that tries to convert Python 2.x code to Python 3.x code by
@@ -39,6 +40,20 @@ Glossary
and loaders (in the :mod:`importlib.abc` module). You can create your own
ABCs with the :mod:`abc` module.
+ annotation
+ A label associated with a variable, a class
+ attribute or a function parameter or return value,
+ used by convention as a :term:`type hint`.
+
+ Annotations of local variables cannot be accessed at runtime, but
+ annotations of global variables, class attributes, and functions
+ are stored in the :attr:`__annotations__`
+ special attribute of modules, classes, and functions,
+ respectively.
+
+ See :term:`variable annotation`, :term:`function annotation`, :pep:`484`
+ and :pep:`526`, which describe this functionality.
+
argument
A value passed to a :term:`function` (or :term:`method`) when calling the
function. There are two kinds of argument:
@@ -80,7 +95,7 @@ Glossary
that it contains :keyword:`yield` expressions for producing a series of
values usable in an :keyword:`async for` loop.
- Usually refers to a asynchronous generator function, but may refer to an
+ Usually refers to an asynchronous generator function, but may refer to an
*asynchronous generator iterator* in some contexts. In cases where the
intended meaning isn't clear, using the full terms avoids ambiguity.
@@ -93,14 +108,14 @@ Glossary
This is an :term:`asynchronous iterator` which when called using the
:meth:`__anext__` method returns an awaitable object which will execute
- that the body of the asynchronous generator function until the
- next :keyword:`yield` expression.
+ the body of the asynchronous generator function until the next
+ :keyword:`yield` expression.
Each :keyword:`yield` temporarily suspends processing, remembering the
location execution state (including local variables and pending
try-statements). When the *asynchronous generator iterator* effectively
resumes with another awaitable returned by :meth:`__anext__`, it
- picks-up where it left-off. See :pep:`492` and :pep:`525`.
+ picks up where it left off. See :pep:`492` and :pep:`525`.
asynchronous iterable
An object, that can be used in an :keyword:`async for` statement.
@@ -108,10 +123,10 @@ Glossary
:meth:`__aiter__` method. Introduced by :pep:`492`.
asynchronous iterator
- An object that implements :meth:`__aiter__` and :meth:`__anext__`
+ An object that implements the :meth:`__aiter__` and :meth:`__anext__`
methods. ``__anext__`` must return an :term:`awaitable` object.
- :keyword:`async for` resolves awaitable returned from asynchronous
- iterator's :meth:`__anext__` method until it raises
+ :keyword:`async for` resolves the awaitables returned by an asynchronous
+ iterator's :meth:`__anext__` method until it raises a
:exc:`StopAsyncIteration` exception. Introduced by :pep:`492`.
attribute
@@ -136,8 +151,8 @@ Glossary
:data:`sys.stdout.buffer`, and instances of :class:`io.BytesIO` and
:class:`gzip.GzipFile`.
- .. seealso::
- A :term:`text file` reads and writes :class:`str` objects.
+ See also :term:`text file` for a file object able to read and write
+ :class:`str` objects.
bytes-like object
An object that supports the :ref:`bufferobjects` and can
@@ -175,13 +190,17 @@ Glossary
normally contain method definitions which operate on instances of the
class.
+ class variable
+ A variable defined in a class and intended to be modified only at
+ class level (i.e., not in an instance of the class).
+
coercion
The implicit conversion of an instance of one type to another during an
operation which involves two arguments of the same type. For example,
``int(3.15)`` converts the floating point number to the integer ``3``, but
in ``3+4.5``, each argument is of a different type (one int, one float),
and both must be converted to the same type before they can be added or it
- will raise a ``TypeError``. Without coercion, all arguments of even
+ will raise a :exc:`TypeError`. Without coercion, all arguments of even
compatible types would have to be normalized to the same value by the
programmer, e.g., ``float(3)+4.5`` rather than just ``3+4.5``.
@@ -202,6 +221,15 @@ Glossary
statement by defining :meth:`__enter__` and :meth:`__exit__` methods.
See :pep:`343`.
+ context variable
+ A variable which can have different values depending on its context.
+ This is similar to Thread-Local Storage in which each execution
+ thread may have a different value for a variable. However, with context
+ variables, there may be several contexts in one execution thread and the
+ main usage for context variables is to keep track of variables in
+ concurrent asynchronous tasks.
+ See :mod:`contextvars`.
+
contiguous
.. index:: C-contiguous, Fortran contiguous
@@ -215,7 +243,7 @@ Glossary
Fortran contiguous arrays, the first index varies the fastest.
coroutine
- Coroutines is a more generalized form of subroutines. Subroutines are
+ Coroutines are a more generalized form of subroutines. Subroutines are
entered at one point and exited at another point. Coroutines can be
entered, exited, and resumed at many different points. They can be
implemented with the :keyword:`async def` statement. See also
@@ -313,7 +341,7 @@ Glossary
names, attribute access, operators or function calls which all return a
value. In contrast to many other languages, not all language constructs
are expressions. There are also :term:`statement`\s which cannot be used
- as expressions, such as :keyword:`if`. Assignments are also statements,
+ as expressions, such as :keyword:`while`. Assignments are also statements,
not expressions.
extension module
@@ -367,16 +395,20 @@ Glossary
and the :ref:`function` section.
function annotation
- An arbitrary metadata value associated with a function parameter or return
- value. Its syntax is explained in section :ref:`function`. Annotations
- may be accessed via the :attr:`__annotations__` special attribute of a
- function object.
+ An :term:`annotation` of a function parameter or return value.
- See also the :term:`variable annotation` glossary entry.
+ Function annotations are usually used for
+ :term:`type hints `: for example, this function is expected to take two
+ :class:`int` arguments and is also expected to have an :class:`int`
+ return value::
- Annotations are meant to provide a standard way for programmers to
- document types of functions they design. See :pep:`484`, which
- describes this functionality.
+ def sum_two_numbers(a: int, b: int) -> int:
+ return a + b
+
+ Function annotation syntax is explained in section :ref:`function`.
+
+ See :term:`variable annotation` and :pep:`484`,
+ which describe this functionality.
__future__
A pseudo-module which programmers can use to enable new language features
@@ -413,16 +445,16 @@ Glossary
Each :keyword:`yield` temporarily suspends processing, remembering the
location execution state (including local variables and pending
- try-statements). When the *generator iterator* resumes, it picks-up where
- it left-off (in contrast to functions which start fresh on every
+ try-statements). When the *generator iterator* resumes, it picks up where
+ it left off (in contrast to functions which start fresh on every
invocation).
.. index:: single: generator expression
generator expression
An expression that returns an iterator. It looks like a normal expression
- followed by a :keyword:`for` expression defining a loop variable, range,
- and an optional :keyword:`if` expression. The combined expression
+ followed by a :keyword:`!for` clause defining a loop variable, range,
+ and an optional :keyword:`!if` clause. The combined expression
generates values for an enclosing function::
>>> sum(i*i for i in range(10)) # sum of squares 0, 1, 4, ... 81
@@ -463,7 +495,7 @@ Glossary
hash-based pyc
- A bytecode cache file that uses the the hash rather than the last-modified
+ A bytecode cache file that uses the hash rather than the last-modified
time of the corresponding source file to determine its validity. See
:ref:`pyc-invalidation`.
@@ -476,8 +508,10 @@ Glossary
Hashability makes an object usable as a dictionary key and a set member,
because these data structures use the hash value internally.
- All of Python's immutable built-in objects are hashable; mutable
- containers (such as lists or dictionaries) are not. Objects which are
+ Most of Python's immutable built-in objects are hashable; mutable
+ containers (such as lists or dictionaries) are not; immutable
+ containers (such as tuples and frozensets) are only hashable if
+ their elements are hashable. Objects which are
instances of user-defined classes are hashable by default. They all
compare unequal (except with themselves), and their hash value is derived
from their :func:`id`.
@@ -603,7 +637,7 @@ Glossary
lambda
An anonymous inline function consisting of a single :term:`expression`
which is evaluated when the function is called. The syntax to create
- a lambda function is ``lambda [arguments]: expression``
+ a lambda function is ``lambda [parameters]: expression``
LBYL
Look before you leap. This coding style explicitly tests for
@@ -620,7 +654,7 @@ Glossary
list
A built-in Python :term:`sequence`. Despite its name it is more akin
to an array in other languages than to a linked list since access to
- elements are O(1).
+ elements is O(1).
list comprehension
A compact way to process all or part of the elements in a sequence and
@@ -636,6 +670,11 @@ Glossary
:term:`finder`. See :pep:`302` for details and
:class:`importlib.abc.Loader` for an :term:`abstract base class`.
+ magic method
+ .. index:: pair: magic; method
+
+ An informal synonym for :term:`special method`.
+
mapping
A container object that supports arbitrary key lookups and implements the
methods specified in the :class:`~collections.abc.Mapping` or
@@ -696,17 +735,28 @@ Glossary
also :term:`immutable`.
named tuple
- Any tuple-like class whose indexable elements are also accessible using
- named attributes (for example, :func:`time.localtime` returns a
- tuple-like object where the *year* is accessible either with an
- index such as ``t[0]`` or with a named attribute like ``t.tm_year``).
-
- A named tuple can be a built-in type such as :class:`time.struct_time`,
- or it can be created with a regular class definition. A full featured
- named tuple can also be created with the factory function
- :func:`collections.namedtuple`. The latter approach automatically
- provides extra features such as a self-documenting representation like
- ``Employee(name='jones', title='programmer')``.
+ The term "named tuple" applies to any type or class that inherits from
+ tuple and whose indexable elements are also accessible using named
+ attributes. The type or class may have other features as well.
+
+ Several built-in types are named tuples, including the values returned
+ by :func:`time.localtime` and :func:`os.stat`. Another example is
+ :data:`sys.float_info`::
+
+ >>> sys.float_info[1] # indexed access
+ 1024
+ >>> sys.float_info.max_exp # named field access
+ 1024
+ >>> isinstance(sys.float_info, tuple) # kind of tuple
+ True
+
+ Some named tuples are built-in types (such as the above examples).
+ Alternatively, a named tuple can be created from a regular class
+ definition that inherits from :class:`tuple` and that defines named
+ fields. Such a class can be written by hand or it can be created with
+ the factory function :func:`collections.namedtuple`. The latter
+ technique also adds some extra methods that may not be found in
+ hand-written or built-in named tuples.
namespace
The place where a variable is stored. Namespaces are implemented as
@@ -837,6 +887,21 @@ Glossary
:class:`str` or :class:`bytes` result instead, respectively. Introduced
by :pep:`519`.
+ PEP
+ Python Enhancement Proposal. A PEP is a design document
+ providing information to the Python community, or describing a new
+ feature for Python or its processes or environment. PEPs should
+ provide a concise technical specification and a rationale for proposed
+ features.
+
+ PEPs are intended to be the primary mechanisms for proposing major new
+ features, for collecting community input on an issue, and for documenting
+ the design decisions that have gone into Python. The PEP author is
+ responsible for building consensus within the community and documenting
+ dissenting opinions.
+
+ See :pep:`1`.
+
portion
A set of files in a single directory (possibly stored in a zip file)
that contribute to a namespace package, as defined in :pep:`420`.
@@ -962,6 +1027,8 @@ Glossary
(subscript) notation uses :class:`slice` objects internally.
special method
+ .. index:: pair: special; method
+
A method that is called implicitly by Python to execute a certain
operation on a type, such as addition. Such methods have names starting
and ending with double underscores. Special methods are documented in
@@ -972,14 +1039,6 @@ Glossary
an :term:`expression` or one of several constructs with a keyword, such
as :keyword:`if`, :keyword:`while` or :keyword:`for`.
- struct sequence
- A tuple with named elements. Struct sequences expose an interface similar
- to :term:`named tuple` in that elements can either be accessed either by
- index or as an attribute. However, they do not have any of the named tuple
- methods like :meth:`~collections.somenamedtuple._make` or
- :meth:`~collections.somenamedtuple._asdict`. Examples of struct sequences
- include :data:`sys.float_info` and the return value of :func:`os.stat`.
-
text encoding
A codec which encodes Unicode strings to bytes.
@@ -991,8 +1050,8 @@ Glossary
:data:`sys.stdin`, :data:`sys.stdout`, and instances of
:class:`io.StringIO`.
- .. seealso::
- A :term:`binary file` reads and write :class:`bytes` objects.
+ See also :term:`binary file` for a file object able to read and write
+ :term:`bytes-like objects `.
triple-quoted string
A string which is bound by three instances of either a quotation mark
@@ -1009,6 +1068,43 @@ Glossary
:attr:`~instance.__class__` attribute or can be retrieved with
``type(obj)``.
+ type alias
+ A synonym for a type, created by assigning the type to an identifier.
+
+ Type aliases are useful for simplifying :term:`type hints `.
+ For example::
+
+ from typing import List, Tuple
+
+ def remove_gray_shades(
+ colors: List[Tuple[int, int, int]]) -> List[Tuple[int, int, int]]:
+ pass
+
+ could be made more readable like this::
+
+ from typing import List, Tuple
+
+ Color = Tuple[int, int, int]
+
+ def remove_gray_shades(colors: List[Color]) -> List[Color]:
+ pass
+
+ See :mod:`typing` and :pep:`484`, which describe this functionality.
+
+ type hint
+ An :term:`annotation` that specifies the expected type for a variable, a class
+ attribute, or a function parameter or return value.
+
+ Type hints are optional and are not enforced by Python but
+ they are useful to static type analysis tools, and aid IDEs with code
+ completion and refactoring.
+
+ Type hints of global variables, class attributes, and functions,
+ but not local variables, can be accessed using
+ :func:`typing.get_type_hints`.
+
+ See :mod:`typing` and :pep:`484`, which describe this functionality.
+
universal newlines
A manner of interpreting text streams in which all of the following are
recognized as ending a line: the Unix end-of-line convention ``'\n'``,
@@ -1017,17 +1113,23 @@ Glossary
:func:`bytes.splitlines` for an additional use.
variable annotation
- A type metadata value associated with a module global variable or
- a class attribute. Its syntax is explained in section :ref:`annassign`.
- Annotations are stored in the :attr:`__annotations__` special
- attribute of a class or module object and can be accessed using
- :func:`typing.get_type_hints`.
+ An :term:`annotation` of a variable or a class attribute.
- See also the :term:`function annotation` glossary entry.
+ When annotating a variable or a class attribute, assignment is optional::
- Annotations are meant to provide a standard way for programmers to
- document types of functions they design. See :pep:`484` and :pep:`526`
- which describe this functionality.
+ class C:
+ field: 'annotation'
+
+ Variable annotations are usually used for
+ :term:`type hints `: for example this variable is expected to take
+ :class:`int` values::
+
+ count: int = 0
+
+ Variable annotation syntax is explained in section :ref:`annassign`.
+
+ See :term:`function annotation`, :pep:`484`
+ and :pep:`526`, which describe this functionality.
virtual environment
A cooperatively isolated runtime environment that allows Python users
diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst
index 9d770f5232b440..e78a022b372faa 100644
--- a/Doc/howto/argparse.rst
+++ b/Doc/howto/argparse.rst
@@ -24,7 +24,7 @@ Concepts
Let's show the sort of functionality that we are going to explore in this
introductory tutorial by making use of the :command:`ls` command:
-.. code-block:: sh
+.. code-block:: shell-session
$ ls
cpython devguide prog.py pypy rm-unused-function.patch
@@ -77,7 +77,7 @@ Let us start with a very simple example which does (almost) nothing::
Following is a result of running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
$ python3 prog.py --help
@@ -119,7 +119,7 @@ An example::
And running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
usage: prog.py [-h] echo
@@ -164,7 +164,7 @@ by reading the source code. So, let's make it a bit more useful::
And we get:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py -h
usage: prog.py [-h] echo
@@ -185,7 +185,7 @@ Now, how about doing something even more useful::
Following is a result of running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
Traceback (most recent call last):
@@ -206,7 +206,7 @@ give it as strings, unless we tell it otherwise. So, let's tell
Following is a result of running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -233,7 +233,7 @@ have a look on how to add optional ones::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py --verbosity 1
verbosity turned on
@@ -279,7 +279,7 @@ Let's modify the code accordingly::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py --verbose
verbosity turned on
@@ -325,7 +325,7 @@ versions of the options. It's quite simple::
And here goes:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py -v
verbosity turned on
@@ -359,7 +359,7 @@ Our program keeps growing in complexity::
And now the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
usage: prog.py [-h] [-v] square
@@ -395,7 +395,7 @@ multiple verbosity values, and actually get to use them::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -429,7 +429,7 @@ Let's fix it by restricting the values the ``--verbosity`` option can accept::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
@@ -470,7 +470,7 @@ verbosity argument (check the output of ``python --help``)::
We have introduced another action, "count",
to count the number of occurrences of a specific optional arguments:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -537,7 +537,7 @@ Let's fix::
And this is what it gives:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 -vvv
the square of 4 equals 16
@@ -581,7 +581,7 @@ it gets the ``None`` value, and that cannot be compared to an int value
And:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -614,7 +614,7 @@ not just squares::
Output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
usage: prog.py [-h] [-v] x y
@@ -652,7 +652,7 @@ to display *more* text instead::
Output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 2
16
@@ -695,7 +695,7 @@ which will be the opposite of the ``--verbose`` one::
Our program is now simpler, and we've lost some functionality for the sake of
demonstration. Anyways, here's the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 2
4^2 == 16
@@ -739,7 +739,7 @@ Note that slight difference in the usage text. Note the ``[-v | -q]``,
which tells us that we can either use ``-v`` or ``-q``,
but not both at the same time:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py --help
usage: prog.py [-h] [-v | -q] x y
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index d3c7d668959e56..ab5f0e4d039e26 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -22,8 +22,8 @@ Argument Clinic How-To
compatibility for future versions. In other words: if you
maintain an external C extension for CPython, you're welcome
to experiment with Argument Clinic in your own code. But the
- version of Argument Clinic that ships with CPython 3.5 *could*
- be totally incompatible and break all your code.
+ version of Argument Clinic that ships with the next version
+ of CPython *could* be totally incompatible and break all your code.
The Goals Of Argument Clinic
============================
@@ -267,12 +267,16 @@ Let's dive in!
should get its own line. All the parameter lines should be
indented from the function name and the docstring.
- The general form of these parameter lines is as follows::
+ The general form of these parameter lines is as follows:
+
+ .. code-block:: none
name_of_parameter: converter
If the parameter has a default value, add that after the
- converter::
+ converter:
+
+ .. code-block:: none
name_of_parameter: converter = default_value
@@ -925,13 +929,17 @@ Parameter default values
------------------------
Default values for parameters can be any of a number of values.
-At their simplest, they can be string, int, or float literals::
+At their simplest, they can be string, int, or float literals:
+
+.. code-block:: none
foo: str = "abc"
bar: int = 123
bat: float = 45.6
-They can also use any of Python's built-in constants::
+They can also use any of Python's built-in constants:
+
+.. code-block:: none
yep: bool = True
nope: bool = False
@@ -959,7 +967,9 @@ It can be an entire expression, using math operators and looking up attributes
on objects. However, this support isn't exactly simple, because of some
non-obvious semantics.
-Consider the following example::
+Consider the following example:
+
+.. code-block:: none
foo: Py_ssize_t = sys.maxsize - 1
@@ -970,7 +980,9 @@ runtime, when the user asks for the function's signature.
What namespace is available when the expression is evaluated? It's evaluated
in the context of the module the builtin came from. So, if your module has an
-attribute called "``max_widgets``", you may simply use it::
+attribute called "``max_widgets``", you may simply use it:
+
+.. code-block:: none
foo: Py_ssize_t = max_widgets
@@ -982,7 +994,9 @@ it's best to restrict yourself to modules that are preloaded by Python itself.)
Evaluating default values only at runtime means Argument Clinic can't compute
the correct equivalent C default value. So you need to tell it explicitly.
When you use an expression, you must also specify the equivalent expression
-in C, using the ``c_default`` parameter to the converter::
+in C, using the ``c_default`` parameter to the converter:
+
+.. code-block:: none
foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1
@@ -1050,7 +1064,7 @@ Currently Argument Clinic supports only a few return converters:
DecodeFSDefault
None of these take parameters. For the first three, return -1 to indicate
-error. For ``DecodeFSDefault``, the return type is ``const char *``; return a NULL
+error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL``
pointer to indicate an error.
(There's also an experimental ``NoneType`` converter, which lets you
@@ -1359,7 +1373,9 @@ Let's start with defining some terminology:
A field, in this context, is a subsection of Clinic's output.
For example, the ``#define`` for the ``PyMethodDef`` structure
is a field, called ``methoddef_define``. Clinic has seven
- different fields it can output per function definition::
+ different fields it can output per function definition:
+
+ .. code-block:: none
docstring_prototype
docstring_definition
@@ -1416,7 +1432,9 @@ Let's start with defining some terminology:
Clinic defines five new directives that let you reconfigure its output.
-The first new directive is ``dump``::
+The first new directive is ``dump``:
+
+.. code-block:: none
dump
@@ -1425,7 +1443,9 @@ the current block, and empties it. This only works with ``buffer`` and
``two-pass`` destinations.
The second new directive is ``output``. The most basic form of ``output``
-is like this::
+is like this:
+
+.. code-block:: none
output
@@ -1433,7 +1453,9 @@ This tells Clinic to output *field* to *destination*. ``output`` also
supports a special meta-destination, called ``everything``, which tells
Clinic to output *all* fields to that *destination*.
-``output`` has a number of other functions::
+``output`` has a number of other functions:
+
+.. code-block:: none
output push
output pop
@@ -1508,7 +1530,9 @@ preset configurations, as follows:
Suppresses the ``impl_prototype``, write the ``docstring_definition``
and ``parser_definition`` to ``buffer``, write everything else to ``block``.
-The third new directive is ``destination``::
+The third new directive is ``destination``:
+
+.. code-block:: none
destination [...]
@@ -1516,7 +1540,9 @@ This performs an operation on the destination named ``name``.
There are two defined subcommands: ``new`` and ``clear``.
-The ``new`` subcommand works like this::
+The ``new`` subcommand works like this:
+
+.. code-block:: none
destination new
@@ -1564,7 +1590,9 @@ There are five destination types:
A two-pass buffer, like the "two-pass" builtin destination above.
-The ``clear`` subcommand works like this::
+The ``clear`` subcommand works like this:
+
+.. code-block:: none
destination clear
@@ -1572,7 +1600,9 @@ It removes all the accumulated text up to this point in the destination.
(I don't know what you'd need this for, but I thought maybe it'd be
useful while someone's experimenting.)
-The fourth new directive is ``set``::
+The fourth new directive is ``set``:
+
+.. code-block:: none
set line_prefix "string"
set line_suffix "string"
@@ -1590,7 +1620,9 @@ Both of these support two format strings:
Turns into the string ``*/``, the end-comment text sequence for C files.
The final new directive is one you shouldn't need to use directly,
-called ``preserve``::
+called ``preserve``:
+
+.. code-block:: none
preserve
@@ -1638,7 +1670,9 @@ like so::
#endif /* HAVE_FUNCTIONNAME */
Then, remove those three lines from the ``PyMethodDef`` structure,
-replacing them with the macro Argument Clinic generated::
+replacing them with the macro Argument Clinic generated:
+
+.. code-block:: none
MODULE_FUNCTIONNAME_METHODDEF
diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst
index 19d65d6996b7f8..cc4b4785b12290 100644
--- a/Doc/howto/curses.rst
+++ b/Doc/howto/curses.rst
@@ -41,7 +41,7 @@ appearance---and the curses library will figure out what control codes
need to be sent to the terminal to produce the right output. curses
doesn't provide many user-interface concepts such as buttons, checkboxes,
or dialogs; if you need such features, consider a user interface library such as
-`Urwid `_.
+`Urwid `_.
The curses library was originally written for BSD Unix; the later System V
versions of Unix from AT&T added many enhancements and new functions. BSD curses
@@ -55,7 +55,7 @@ everything, though.
The Windows version of Python doesn't include the :mod:`curses`
module. A ported version called `UniCurses
-`_ is available. You could
+`_ is available. You could
also try `the Console module `_
written by Fredrik Lundh, which doesn't
use the same API as curses but provides cursor-addressable text output
@@ -432,7 +432,7 @@ User Input
The C curses library offers only very simple input mechanisms. Python's
:mod:`curses` module adds a basic text-input widget. (Other libraries
-such as `Urwid `_ have more extensive
+such as `Urwid `_ have more extensive
collections of widgets.)
There are two methods for getting input from a window:
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index 5e85a9aa6594e4..3d1da5ac1b7b85 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -11,7 +11,7 @@ Abstract
--------
Defines descriptors, summarizes the protocol, and shows how descriptors are
-called. Examines a custom descriptor and several built-in python descriptors
+called. Examines a custom descriptor and several built-in Python descriptors
including functions, properties, static methods, and class methods. Shows how
each works by giving a pure Python equivalent and a sample application.
@@ -48,11 +48,11 @@ a flexible set of new tools for everyday Python programs.
Descriptor Protocol
-------------------
-``descr.__get__(self, obj, type=None) --> value``
+``descr.__get__(self, obj, type=None) -> value``
-``descr.__set__(self, obj, value) --> None``
+``descr.__set__(self, obj, value) -> None``
-``descr.__delete__(self, obj) --> None``
+``descr.__delete__(self, obj) -> None``
That is all there is to it. Define any of these methods and an object is
considered a descriptor and can override default behavior upon being looked up
@@ -275,7 +275,7 @@ variable name.
To support method calls, functions include the :meth:`__get__` method for
binding methods during attribute access. This means that all functions are
non-data descriptors which return bound methods when they are invoked from an
-object. In pure python, it works like this::
+object. In pure Python, it works like this::
class Function(object):
. . .
@@ -372,9 +372,9 @@ calls are unexciting::
... print(x)
... f = staticmethod(f)
...
- >>> print(E.f(3))
+ >>> E.f(3)
3
- >>> print(E().f(3))
+ >>> E().f(3)
3
Using the non-data descriptor protocol, a pure Python version of
diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst
index 40601812a77cb5..74e861480d2ff8 100644
--- a/Doc/howto/functional.rst
+++ b/Doc/howto/functional.rst
@@ -198,7 +198,7 @@ for it.
You can experiment with the iteration interface manually:
- >>> L = [1,2,3]
+ >>> L = [1, 2, 3]
>>> it = iter(L)
>>> it #doctest: +ELLIPSIS
<...iterator object at ...>
@@ -229,7 +229,7 @@ iterator. These two statements are equivalent::
Iterators can be materialized as lists or tuples by using the :func:`list` or
:func:`tuple` constructor functions:
- >>> L = [1,2,3]
+ >>> L = [1, 2, 3]
>>> iterator = iter(L)
>>> t = tuple(iterator)
>>> t
@@ -238,10 +238,10 @@ Iterators can be materialized as lists or tuples by using the :func:`list` or
Sequence unpacking also supports iterators: if you know an iterator will return
N elements, you can unpack them into an N-tuple:
- >>> L = [1,2,3]
+ >>> L = [1, 2, 3]
>>> iterator = iter(L)
- >>> a,b,c = iterator
- >>> a,b,c
+ >>> a, b, c = iterator
+ >>> a, b, c
(1, 2, 3)
Built-in functions such as :func:`max` and :func:`min` can take a single
@@ -273,23 +273,24 @@ dictionary's keys::
>>> m = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
... 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
- >>> for key in m: #doctest: +SKIP
+ >>> for key in m:
... print(key, m[key])
- Mar 3
+ Jan 1
Feb 2
- Aug 8
- Sep 9
+ Mar 3
Apr 4
+ May 5
Jun 6
Jul 7
- Jan 1
- May 5
+ Aug 8
+ Sep 9
+ Oct 10
Nov 11
Dec 12
- Oct 10
-Note that the order is essentially random, because it's based on the hash
-ordering of the objects in the dictionary.
+Note that starting with Python 3.7, dictionary iteration order is guaranteed
+to be the same as the insertion order. In earlier versions, the behaviour was
+unspecified and could vary between implementations.
Applying :func:`iter` to a dictionary always loops over the keys, but
dictionaries have methods that return other iterators. If you want to iterate
@@ -301,8 +302,8 @@ The :func:`dict` constructor can accept an iterator that returns a finite stream
of ``(key, value)`` tuples:
>>> L = [('Italy', 'Rome'), ('France', 'Paris'), ('US', 'Washington DC')]
- >>> dict(iter(L)) #doctest: +SKIP
- {'Italy': 'Rome', 'US': 'Washington DC', 'France': 'Paris'}
+ >>> dict(iter(L))
+ {'Italy': 'Rome', 'France': 'Paris', 'US': 'Washington DC'}
Files also support iteration by calling the :meth:`~io.TextIOBase.readline`
method until there are no more lines in the file. This means you can read each
@@ -410,7 +411,7 @@ lengths of all the sequences. If you have two lists of length 3, the output
list is 9 elements long:
>>> seq1 = 'abc'
- >>> seq2 = (1,2,3)
+ >>> seq2 = (1, 2, 3)
>>> [(x, y) for x in seq1 for y in seq2] #doctest: +NORMALIZE_WHITESPACE
[('a', 1), ('a', 2), ('a', 3),
('b', 1), ('b', 2), ('b', 3),
@@ -478,7 +479,7 @@ Here's a sample usage of the ``generate_ints()`` generator:
File "stdin", line 2, in generate_ints
StopIteration
-You could equally write ``for i in generate_ints(5)``, or ``a,b,c =
+You could equally write ``for i in generate_ints(5)``, or ``a, b, c =
generate_ints(3)``.
Inside a generator function, ``return value`` causes ``StopIteration(value)``
@@ -694,17 +695,17 @@ truth values of an iterable's contents. :func:`any` returns ``True`` if any ele
in the iterable is a true value, and :func:`all` returns ``True`` if all of the
elements are true values:
- >>> any([0,1,0])
+ >>> any([0, 1, 0])
True
- >>> any([0,0,0])
+ >>> any([0, 0, 0])
False
- >>> any([1,1,1])
+ >>> any([1, 1, 1])
True
- >>> all([0,1,0])
+ >>> all([0, 1, 0])
False
- >>> all([0,0,0])
+ >>> all([0, 0, 0])
False
- >>> all([1,1,1])
+ >>> all([1, 1, 1])
True
@@ -763,7 +764,7 @@ which defaults to 0, and the interval between numbers, which defaults to 1::
a provided iterable and returns a new iterator that returns its elements from
first to last. The new iterator will repeat these elements infinitely. ::
- itertools.cycle([1,2,3,4,5]) =>
+ itertools.cycle([1, 2, 3, 4, 5]) =>
1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
:func:`itertools.repeat(elem, [n]) ` returns the provided
@@ -874,7 +875,7 @@ iterable's results. ::
iterators and returns only those elements of *data* for which the corresponding
element of *selectors* is true, stopping whenever either one is exhausted::
- itertools.compress([1,2,3,4,5], [True, True, False, False, True]) =>
+ itertools.compress([1, 2, 3, 4, 5], [True, True, False, False, True]) =>
1, 2, 5
@@ -1034,7 +1035,7 @@ first calculation. ::
Traceback (most recent call last):
...
TypeError: reduce() of empty sequence with no initial value
- >>> functools.reduce(operator.mul, [1,2,3], 1)
+ >>> functools.reduce(operator.mul, [1, 2, 3], 1)
6
>>> functools.reduce(operator.mul, [], 1)
1
@@ -1044,9 +1045,9 @@ elements of the iterable. This case is so common that there's a special
built-in called :func:`sum` to compute it:
>>> import functools, operator
- >>> functools.reduce(operator.add, [1,2,3,4], 0)
+ >>> functools.reduce(operator.add, [1, 2, 3, 4], 0)
10
- >>> sum([1,2,3,4])
+ >>> sum([1, 2, 3, 4])
10
>>> sum([])
0
@@ -1056,11 +1057,11 @@ write the obvious :keyword:`for` loop::
import functools
# Instead of:
- product = functools.reduce(operator.mul, [1,2,3], 1)
+ product = functools.reduce(operator.mul, [1, 2, 3], 1)
# You can write:
product = 1
- for i in [1,2,3]:
+ for i in [1, 2, 3]:
product *= i
A related function is :func:`itertools.accumulate(iterable, func=operator.add)
@@ -1068,10 +1069,10 @@ A related function is :func:`itertools.accumulate(iterable, func=operator.add)
returning only the final result, :func:`accumulate` returns an iterator that
also yields each partial result::
- itertools.accumulate([1,2,3,4,5]) =>
+ itertools.accumulate([1, 2, 3, 4, 5]) =>
1, 3, 6, 10, 15
- itertools.accumulate([1,2,3,4,5], operator.mul) =>
+ itertools.accumulate([1, 2, 3, 4, 5], operator.mul) =>
1, 2, 6, 24, 120
@@ -1107,7 +1108,7 @@ need to define a new function at all::
existing_files = filter(os.path.exists, file_list)
If the function you need doesn't exist, you need to write it. One way to write
-small functions is to use the :keyword:`lambda` statement. ``lambda`` takes a
+small functions is to use the :keyword:`lambda` expression. ``lambda`` takes a
number of parameters and an expression combining these parameters, and creates
an anonymous function that returns the value of the expression::
@@ -1155,7 +1156,7 @@ But it would be best of all if I had simply used a ``for`` loop::
Or the :func:`sum` built-in and a generator expression::
- total = sum(b for a,b in items)
+ total = sum(b for a, b in items)
Many uses of :func:`functools.reduce` are clearer when written as ``for`` loops.
@@ -1228,9 +1229,9 @@ Text Processing".
Mertz also wrote a 3-part series of articles on functional programming
for IBM's DeveloperWorks site; see
-`part 1 `__,
-`part 2 `__, and
-`part 3 `__,
+`part 1 `__,
+`part 2 `__, and
+`part 3 `__,
Python documentation
diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst
index b9c51a4a4538ab..50cde3595034b5 100644
--- a/Doc/howto/instrumentation.rst
+++ b/Doc/howto/instrumentation.rst
@@ -254,11 +254,15 @@ and the remainder indicates the call/return hierarchy as the script executes.
For a `--enable-shared` build of CPython, the markers are contained within the
libpython shared library, and the probe's dotted path needs to reflect this. For
-example, this line from the above example::
+example, this line from the above example:
+
+.. code-block:: none
probe process("python").mark("function__entry") {
-should instead read::
+should instead read:
+
+.. code-block:: none
probe process("python").library("libpython3.6dm.so.1.0").mark("function__entry") {
@@ -365,13 +369,13 @@ available:
.. c:function:: python.function.entry(str filename, str funcname, int lineno, frameptr)
This probe point indicates that execution of a Python function has begun.
- It is only triggered for pure-python (bytecode) functions.
+ It is only triggered for pure-Python (bytecode) functions.
.. c:function:: python.function.return(str filename, str funcname, int lineno, frameptr)
This probe point is the converse of :c:func:`python.function.return`, and
indicates that execution of a Python function has ended (either via
- ``return``, or via an exception). It is only triggered for pure-python
+ ``return``, or via an exception). It is only triggered for pure-Python
(bytecode) functions.
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 4d2d052d291788..6ab1e39f0652bd 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -72,7 +72,9 @@ Here is the auxiliary module::
def some_function():
module_logger.info('received a call to "some_function"')
-The output looks like this::
+The output looks like this:
+
+.. code-block:: none
2005-03-23 23:47:11,663 - spam_application - INFO -
creating an instance of auxiliary_module.Auxiliary
@@ -127,7 +129,9 @@ shows logging from the main (initial) thread and another thread::
if __name__ == '__main__':
main()
-When run, the script should print something like the following::
+When run, the script should print something like the following:
+
+.. code-block:: none
0 Thread-1 Hi from myfunc
3 MainThread Hello from main
@@ -182,7 +186,7 @@ previous simple module-based configuration example::
# 'application' code
logger.debug('debug message')
logger.info('info message')
- logger.warn('warn message')
+ logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
@@ -240,14 +244,18 @@ messages should not. Here's how you can achieve this::
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')
-When you run this, on the console you will see ::
+When you run this, on the console you will see
+
+.. code-block:: none
root : INFO Jackdaws love my big sphinx of quartz.
myapp.area1 : INFO How quickly daft jumping zebras vex.
myapp.area2 : WARNING Jail zesty vixen who grabbed pay from quack.
myapp.area2 : ERROR The five boxing wizards jump quickly.
-and in the file you will see something like ::
+and in the file you will see something like
+
+.. code-block:: none
10-22 22:19 root INFO Jackdaws love my big sphinx of quartz.
10-22 22:19 myapp.area1 DEBUG Quick zephyrs blow, vexing daft Jim.
@@ -287,7 +295,7 @@ Here is an example of a module using the logging configuration server::
while True:
logger.debug('debug message')
logger.info('info message')
- logger.warn('warn message')
+ logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
time.sleep(5)
@@ -515,7 +523,9 @@ module. Here is a basic working example::
main()
First run the server, and then the client. On the client side, nothing is
-printed on the console; on the server side, you should see something like::
+printed on the console; on the server side, you should see something like:
+
+.. code-block:: none
About to start TCP server...
59 root INFO Jackdaws love my big sphinx of quartz.
@@ -675,7 +685,9 @@ script::
lvlname = logging.getLevelName(lvl)
a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
-which, when run, produces something like::
+which, when run, produces something like:
+
+.. code-block:: none
2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred A debug message
2010-09-06 22:38:15,300 a.b.c INFO IP: 192.168.0.1 User: sheila An info message with some parameters
@@ -937,6 +949,41 @@ This variant shows how you can e.g. apply configuration for particular loggers
machinery in the main process (even though the logging events are generated in
the worker processes) to direct the messages to the appropriate destinations.
+Using concurrent.futures.ProcessPoolExecutor
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you want to use :class:`concurrent.futures.ProcessPoolExecutor` to start
+your worker processes, you need to create the queue slightly differently.
+Instead of
+
+.. code-block:: python
+
+ queue = multiprocessing.Queue(-1)
+
+you should use
+
+.. code-block:: python
+
+ queue = multiprocessing.Manager().Queue(-1) # also works with the examples above
+
+and you can then replace the worker creation from this::
+
+ workers = []
+ for i in range(10):
+ worker = multiprocessing.Process(target=worker_process,
+ args=(queue, worker_configurer))
+ workers.append(worker)
+ worker.start()
+ for w in workers:
+ w.join()
+
+to this (remembering to first import :mod:`concurrent.futures`)::
+
+ with concurrent.futures.ProcessPoolExecutor(max_workers=10) as executor:
+ for i in range(10):
+ executor.submit(worker_process, queue, worker_configurer)
+
+
Using file rotation
-------------------
@@ -976,7 +1023,9 @@ logging package provides a :class:`~handlers.RotatingFileHandler`::
print(filename)
The result should be 6 separate files, each with part of the log history for the
-application::
+application:
+
+.. code-block:: none
logging_rotatingfile_example.out
logging_rotatingfile_example.out.1
@@ -1638,11 +1687,11 @@ works::
Inserting a BOM into messages sent to a SysLogHandler
-----------------------------------------------------
-`RFC 5424 `_ requires that a
+:rfc:`5424` requires that a
Unicode message be sent to a syslog daemon as a set of bytes which have the
following structure: an optional pure-ASCII component, followed by a UTF-8 Byte
-Order Mark (BOM), followed by Unicode encoded using UTF-8. (See the `relevant
-section of the specification `_.)
+Order Mark (BOM), followed by Unicode encoded using UTF-8. (See the
+:rfc:`relevant section of the specification <5424#section-6>`.)
In Python 3.1, code was added to
:class:`~logging.handlers.SysLogHandler` to insert a BOM into the message, but
@@ -1652,7 +1701,7 @@ appear before it.
As this behaviour is broken, the incorrect BOM insertion code is being removed
from Python 3.2.4 and later. However, it is not being replaced, and if you
-want to produce RFC 5424-compliant messages which include a BOM, an optional
+want to produce :rfc:`5424`-compliant messages which include a BOM, an optional
pure-ASCII sequence before it and arbitrary Unicode after it, encoded using
UTF-8, then you need to do the following:
@@ -1675,7 +1724,7 @@ UTF-8, then you need to do the following:
The formatted message *will* be encoded using UTF-8 encoding by
``SysLogHandler``. If you follow the above rules, you should be able to produce
-RFC 5424-compliant messages. If you don't, logging may not complain, but your
+:rfc:`5424`-compliant messages. If you don't, logging may not complain, but your
messages will not be RFC 5424-compliant, and your syslog daemon may complain.
@@ -1706,7 +1755,9 @@ which uses JSON to serialise the event in a machine-parseable manner::
logging.basicConfig(level=logging.INFO, format='%(message)s')
logging.info(_('message 1', foo='bar', bar='baz', num=123, fnum=123.456))
-If the above script is run, it prints::
+If the above script is run, it prints:
+
+.. code-block:: none
message 1 >>> {"fnum": 123.456, "num": 123, "bar": "baz", "foo": "bar"}
@@ -1753,7 +1804,9 @@ as in the following complete example::
if __name__ == '__main__':
main()
-When the above script is run, it prints::
+When the above script is run, it prints:
+
+.. code-block:: none
message 1 >>> {"snowman": "\u2603", "set_value": [1, 2, 3]}
@@ -2083,7 +2136,9 @@ most obvious, but you can provide any callable which returns a
This example shows how you can pass configuration data to the callable which
constructs the instance, in the form of keyword parameters. When run, the above
-script will print::
+script will print:
+
+.. code-block:: none
changed: hello
@@ -2150,7 +2205,9 @@ class, as shown in the following example::
if __name__ == '__main__':
main()
-When run, this produces a file with exactly two lines::
+When run, this produces a file with exactly two lines:
+
+.. code-block:: none
28/01/2015 07:21:23|INFO|Sample message|
28/01/2015 07:21:23|ERROR|ZeroDivisionError: integer division or modulo by zero|'Traceback (most recent call last):\n File "logtest7.py", line 30, in main\n x = 1 / 0\nZeroDivisionError: integer division or modulo by zero'|
@@ -2245,9 +2302,9 @@ The script just arranges to decorate ``foo`` with a decorator which will do the
conditional logging that's required. The decorator takes a logger as a parameter
and attaches a memory handler for the duration of the call to the decorated
function. The decorator can be additionally parameterised using a target handler,
-a level at which flushing should occur, and a capacity for the buffer. These
-default to a :class:`~logging.StreamHandler` which writes to ``sys.stderr``,
-``logging.ERROR`` and ``100`` respectively.
+a level at which flushing should occur, and a capacity for the buffer (number of
+records buffered). These default to a :class:`~logging.StreamHandler` which
+writes to ``sys.stderr``, ``logging.ERROR`` and ``100`` respectively.
Here's the script::
@@ -2312,7 +2369,9 @@ Here's the script::
write_line('Calling decorated foo with True')
assert decorated_foo(True)
-When this script is run, the following output should be observed::
+When this script is run, the following output should be observed:
+
+.. code-block:: none
Calling undecorated foo with False
about to log at DEBUG ...
@@ -2408,7 +2467,9 @@ the following complete example::
logging.config.dictConfig(LOGGING)
logging.warning('The local time is %s', time.asctime())
-When this script is run, it should print something like::
+When this script is run, it should print something like:
+
+.. code-block:: none
2015-10-17 12:53:29,501 The local time is Sat Oct 17 13:53:29 2015
2015-10-17 13:53:29,501 The local time is Sat Oct 17 13:53:29 2015
@@ -2523,3 +2584,399 @@ In this case, the message #5 printed to ``stdout`` doesn't appear, as expected.
Of course, the approach described here can be generalised, for example to attach
logging filters temporarily. Note that the above code works in Python 2 as well
as Python 3.
+
+
+.. _starter-template:
+
+A CLI application starter template
+----------------------------------
+
+Here's an example which shows how you can:
+
+* Use a logging level based on command-line arguments
+* Dispatch to multiple subcommands in separate files, all logging at the same
+ level in a consistent way
+* Make use of simple, minimal configuration
+
+Suppose we have a command-line application whose job is to stop, start or
+restart some services. This could be organised for the purposes of illustration
+as a file ``app.py`` that is the main script for the application, with individual
+commands implemented in ``start.py``, ``stop.py`` and ``restart.py``. Suppose
+further that we want to control the verbosity of the application via a
+command-line argument, defaulting to ``logging.INFO``. Here's one way that
+``app.py`` could be written::
+
+ import argparse
+ import importlib
+ import logging
+ import os
+ import sys
+
+ def main(args=None):
+ scriptname = os.path.basename(__file__)
+ parser = argparse.ArgumentParser(scriptname)
+ levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
+ parser.add_argument('--log-level', default='INFO', choices=levels)
+ subparsers = parser.add_subparsers(dest='command',
+ help='Available commands:')
+ start_cmd = subparsers.add_parser('start', help='Start a service')
+ start_cmd.add_argument('name', metavar='NAME',
+ help='Name of service to start')
+ stop_cmd = subparsers.add_parser('stop',
+ help='Stop one or more services')
+ stop_cmd.add_argument('names', metavar='NAME', nargs='+',
+ help='Name of service to stop')
+ restart_cmd = subparsers.add_parser('restart',
+ help='Restart one or more services')
+ restart_cmd.add_argument('names', metavar='NAME', nargs='+',
+ help='Name of service to restart')
+ options = parser.parse_args()
+ # the code to dispatch commands could all be in this file. For the purposes
+ # of illustration only, we implement each command in a separate module.
+ try:
+ mod = importlib.import_module(options.command)
+ cmd = getattr(mod, 'command')
+ except (ImportError, AttributeError):
+ print('Unable to find the code for command \'%s\'' % options.command)
+ return 1
+ # Could get fancy here and load configuration from file or dictionary
+ logging.basicConfig(level=options.log_level,
+ format='%(levelname)s %(name)s %(message)s')
+ cmd(options)
+
+ if __name__ == '__main__':
+ sys.exit(main())
+
+And the ``start``, ``stop`` and ``restart`` commands can be implemented in
+separate modules, like so for starting::
+
+ # start.py
+ import logging
+
+ logger = logging.getLogger(__name__)
+
+ def command(options):
+ logger.debug('About to start %s', options.name)
+ # actually do the command processing here ...
+ logger.info('Started the \'%s\' service.', options.name)
+
+and thus for stopping::
+
+ # stop.py
+ import logging
+
+ logger = logging.getLogger(__name__)
+
+ def command(options):
+ n = len(options.names)
+ if n == 1:
+ plural = ''
+ services = '\'%s\'' % options.names[0]
+ else:
+ plural = 's'
+ services = ', '.join('\'%s\'' % name for name in options.names)
+ i = services.rfind(', ')
+ services = services[:i] + ' and ' + services[i + 2:]
+ logger.debug('About to stop %s', services)
+ # actually do the command processing here ...
+ logger.info('Stopped the %s service%s.', services, plural)
+
+and similarly for restarting::
+
+ # restart.py
+ import logging
+
+ logger = logging.getLogger(__name__)
+
+ def command(options):
+ n = len(options.names)
+ if n == 1:
+ plural = ''
+ services = '\'%s\'' % options.names[0]
+ else:
+ plural = 's'
+ services = ', '.join('\'%s\'' % name for name in options.names)
+ i = services.rfind(', ')
+ services = services[:i] + ' and ' + services[i + 2:]
+ logger.debug('About to restart %s', services)
+ # actually do the command processing here ...
+ logger.info('Restarted the %s service%s.', services, plural)
+
+If we run this application with the default log level, we get output like this:
+
+.. code-block:: shell-session
+
+ $ python app.py start foo
+ INFO start Started the 'foo' service.
+
+ $ python app.py stop foo bar
+ INFO stop Stopped the 'foo' and 'bar' services.
+
+ $ python app.py restart foo bar baz
+ INFO restart Restarted the 'foo', 'bar' and 'baz' services.
+
+The first word is the logging level, and the second word is the module or
+package name of the place where the event was logged.
+
+If we change the logging level, then we can change the information sent to the
+log. For example, if we want more information:
+
+.. code-block:: shell-session
+
+ $ python app.py --log-level DEBUG start foo
+ DEBUG start About to start foo
+ INFO start Started the 'foo' service.
+
+ $ python app.py --log-level DEBUG stop foo bar
+ DEBUG stop About to stop 'foo' and 'bar'
+ INFO stop Stopped the 'foo' and 'bar' services.
+
+ $ python app.py --log-level DEBUG restart foo bar baz
+ DEBUG restart About to restart 'foo', 'bar' and 'baz'
+ INFO restart Restarted the 'foo', 'bar' and 'baz' services.
+
+And if we want less:
+
+.. code-block:: shell-session
+
+ $ python app.py --log-level WARNING start foo
+ $ python app.py --log-level WARNING stop foo bar
+ $ python app.py --log-level WARNING restart foo bar baz
+
+In this case, the commands don't print anything to the console, since nothing
+at ``WARNING`` level or above is logged by them.
+
+.. _qt-gui:
+
+A Qt GUI for logging
+--------------------
+
+A question that comes up from time to time is about how to log to a GUI
+application. The `Qt `_ framework is a popular
+cross-platform UI framework with Python bindings using `PySide2
+`_ or `PyQt5
+`_ libraries.
+
+The following example shows how to log to a Qt GUI. This introduces a simple
+``QtHandler`` class which takes a callable, which should be a slot in the main
+thread that does GUI updates. A worker thread is also created to show how you
+can log to the GUI from both the UI itself (via a button for manual logging)
+as well as a worker thread doing work in the background (here, just logging
+messages at random levels with random short delays in between).
+
+The worker thread is implemented using Qt's ``QThread`` class rather than the
+:mod:`threading` module, as there are circumstances where one has to use
+``QThread``, which offers better integration with other ``Qt`` components.
+
+The code should work with recent releases of either ``PySide2`` or ``PyQt5``.
+You should be able to adapt the approach to earlier versions of Qt. Please
+refer to the comments in the code snippet for more detailed information.
+
+.. code-block:: python3
+
+ import datetime
+ import logging
+ import random
+ import sys
+ import time
+
+ # Deal with minor differences between PySide2 and PyQt5
+ try:
+ from PySide2 import QtCore, QtGui, QtWidgets
+ Signal = QtCore.Signal
+ Slot = QtCore.Slot
+ except ImportError:
+ from PyQt5 import QtCore, QtGui, QtWidgets
+ Signal = QtCore.pyqtSignal
+ Slot = QtCore.pyqtSlot
+
+
+ logger = logging.getLogger(__name__)
+
+
+ #
+ # Signals need to be contained in a QObject or subclass in order to be correctly
+ # initialized.
+ #
+ class Signaller(QtCore.QObject):
+ signal = Signal(str, logging.LogRecord)
+
+ #
+ # Output to a Qt GUI is only supposed to happen on the main thread. So, this
+ # handler is designed to take a slot function which is set up to run in the main
+ # thread. In this example, the function takes a string argument which is a
+ # formatted log message, and the log record which generated it. The formatted
+ # string is just a convenience - you could format a string for output any way
+ # you like in the slot function itself.
+ #
+ # You specify the slot function to do whatever GUI updates you want. The handler
+ # doesn't know or care about specific UI elements.
+ #
+ class QtHandler(logging.Handler):
+ def __init__(self, slotfunc, *args, **kwargs):
+ super(QtHandler, self).__init__(*args, **kwargs)
+ self.signaller = Signaller()
+ self.signaller.signal.connect(slotfunc)
+
+ def emit(self, record):
+ s = self.format(record)
+ self.signaller.signal.emit(s, record)
+
+ #
+ # This example uses QThreads, which means that the threads at the Python level
+ # are named something like "Dummy-1". The function below gets the Qt name of the
+ # current thread.
+ #
+ def ctname():
+ return QtCore.QThread.currentThread().objectName()
+
+
+ #
+ # Used to generate random levels for logging.
+ #
+ LEVELS = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR,
+ logging.CRITICAL)
+
+ #
+ # This worker class represents work that is done in a thread separate to the
+ # main thread. The way the thread is kicked off to do work is via a button press
+ # that connects to a slot in the worker.
+ #
+ # Because the default threadName value in the LogRecord isn't much use, we add
+ # a qThreadName which contains the QThread name as computed above, and pass that
+ # value in an "extra" dictionary which is used to update the LogRecord with the
+ # QThread name.
+ #
+ # This example worker just outputs messages sequentially, interspersed with
+ # random delays of the order of a few seconds.
+ #
+ class Worker(QtCore.QObject):
+ @Slot()
+ def start(self):
+ extra = {'qThreadName': ctname() }
+ logger.debug('Started work', extra=extra)
+ i = 1
+ # Let the thread run until interrupted. This allows reasonably clean
+ # thread termination.
+ while not QtCore.QThread.currentThread().isInterruptionRequested():
+ delay = 0.5 + random.random() * 2
+ time.sleep(delay)
+ level = random.choice(LEVELS)
+ logger.log(level, 'Message after delay of %3.1f: %d', delay, i, extra=extra)
+ i += 1
+
+ #
+ # Implement a simple UI for this cookbook example. This contains:
+ #
+ # * A read-only text edit window which holds formatted log messages
+ # * A button to start work and log stuff in a separate thread
+ # * A button to log something from the main thread
+ # * A button to clear the log window
+ #
+ class Window(QtWidgets.QWidget):
+
+ COLORS = {
+ logging.DEBUG: 'black',
+ logging.INFO: 'blue',
+ logging.WARNING: 'orange',
+ logging.ERROR: 'red',
+ logging.CRITICAL: 'purple',
+ }
+
+ def __init__(self, app):
+ super(Window, self).__init__()
+ self.app = app
+ self.textedit = te = QtWidgets.QPlainTextEdit(self)
+ # Set whatever the default monospace font is for the platform
+ f = QtGui.QFont('nosuchfont')
+ f.setStyleHint(f.Monospace)
+ te.setFont(f)
+ te.setReadOnly(True)
+ PB = QtWidgets.QPushButton
+ self.work_button = PB('Start background work', self)
+ self.log_button = PB('Log a message at a random level', self)
+ self.clear_button = PB('Clear log window', self)
+ self.handler = h = QtHandler(self.update_status)
+ # Remember to use qThreadName rather than threadName in the format string.
+ fs = '%(asctime)s %(qThreadName)-12s %(levelname)-8s %(message)s'
+ formatter = logging.Formatter(fs)
+ h.setFormatter(formatter)
+ logger.addHandler(h)
+ # Set up to terminate the QThread when we exit
+ app.aboutToQuit.connect(self.force_quit)
+
+ # Lay out all the widgets
+ layout = QtWidgets.QVBoxLayout(self)
+ layout.addWidget(te)
+ layout.addWidget(self.work_button)
+ layout.addWidget(self.log_button)
+ layout.addWidget(self.clear_button)
+ self.setFixedSize(900, 400)
+
+ # Connect the non-worker slots and signals
+ self.log_button.clicked.connect(self.manual_update)
+ self.clear_button.clicked.connect(self.clear_display)
+
+ # Start a new worker thread and connect the slots for the worker
+ self.start_thread()
+ self.work_button.clicked.connect(self.worker.start)
+ # Once started, the button should be disabled
+ self.work_button.clicked.connect(lambda : self.work_button.setEnabled(False))
+
+ def start_thread(self):
+ self.worker = Worker()
+ self.worker_thread = QtCore.QThread()
+ self.worker.setObjectName('Worker')
+ self.worker_thread.setObjectName('WorkerThread') # for qThreadName
+ self.worker.moveToThread(self.worker_thread)
+ # This will start an event loop in the worker thread
+ self.worker_thread.start()
+
+ def kill_thread(self):
+ # Just tell the worker to stop, then tell it to quit and wait for that
+ # to happen
+ self.worker_thread.requestInterruption()
+ if self.worker_thread.isRunning():
+ self.worker_thread.quit()
+ self.worker_thread.wait()
+ else:
+ print('worker has already exited.')
+
+ def force_quit(self):
+ # For use when the window is closed
+ if self.worker_thread.isRunning():
+ self.kill_thread()
+
+ # The functions below update the UI and run in the main thread because
+ # that's where the slots are set up
+
+ @Slot(str, logging.LogRecord)
+ def update_status(self, status, record):
+ color = self.COLORS.get(record.levelno, 'black')
+ s = '%s
' % (color, status)
+ self.textedit.appendHtml(s)
+
+ @Slot()
+ def manual_update(self):
+ # This function uses the formatted message passed in, but also uses
+ # information from the record to format the message in an appropriate
+ # color according to its severity (level).
+ level = random.choice(LEVELS)
+ extra = {'qThreadName': ctname() }
+ logger.log(level, 'Manually logged!', extra=extra)
+
+ @Slot()
+ def clear_display(self):
+ self.textedit.clear()
+
+
+ def main():
+ QtCore.QThread.currentThread().setObjectName('MainThread')
+ logging.getLogger().setLevel(logging.DEBUG)
+ app = QtWidgets.QApplication(sys.argv)
+ example = Window(app)
+ example.show()
+ sys.exit(app.exec_())
+
+ if __name__=='__main__':
+ main()
diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst
index 4ee68b4747eb00..7a68ca89199c77 100644
--- a/Doc/howto/logging.rst
+++ b/Doc/howto/logging.rst
@@ -134,7 +134,9 @@ interpreter, and don't just continue from the session described above::
logging.warning('And this, too')
And now if we open the file and look at what we have, we should find the log
-messages::
+messages:
+
+.. code-block:: none
DEBUG:root:This message should go to the log file
INFO:root:So should this
@@ -144,7 +146,9 @@ This example also shows how you can set the logging level which acts as the
threshold for tracking. In this case, because we set the threshold to
``DEBUG``, all of the messages were printed.
-If you want to set the logging level from a command-line option such as::
+If you want to set the logging level from a command-line option such as:
+
+.. code-block:: none
--log=INFO
@@ -208,7 +212,9 @@ could organize logging in it::
def do_something():
logging.info('Doing something')
-If you run *myapp.py*, you should see this in *myapp.log*::
+If you run *myapp.py*, you should see this in *myapp.log*:
+
+.. code-block:: none
INFO:root:Started
INFO:root:Doing something
@@ -258,7 +264,9 @@ specify the format you want to use::
logging.info('So should this')
logging.warning('And this, too')
-which would print::
+which would print:
+
+.. code-block:: none
DEBUG:This message should appear on the console
INFO:So should this
@@ -282,19 +290,23 @@ your format string::
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.')
-which should print something like this::
+which should print something like this:
+
+.. code-block:: none
2010-12-12 11:41:42,612 is when this event was logged.
-The default format for date/time display (shown above) is ISO8601. If you need
-more control over the formatting of the date/time, provide a *datefmt*
-argument to ``basicConfig``, as in this example::
+The default format for date/time display (shown above) is like ISO8601 or
+:rfc:`3339`. If you need more control over the formatting of the date/time, provide
+a *datefmt* argument to ``basicConfig``, as in this example::
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')
-which would display something like this::
+which would display something like this:
+
+.. code-block:: none
12/12/2010 11:46:36 AM is when this event was logged.
@@ -376,7 +388,9 @@ if no destination is set; and if one is not set, they will set a destination
of the console (``sys.stderr``) and a default format for the displayed
message before delegating to the root logger to do the actual message output.
-The default format set by :func:`basicConfig` for messages is::
+The default format set by :func:`basicConfig` for messages is:
+
+.. code-block:: none
severity:logger name:message
@@ -522,7 +536,9 @@ indicator.
.. method:: logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
If there is no message format string, the default is to use the
-raw message. If there is no date format string, the default date format is::
+raw message. If there is no date format string, the default date format is:
+
+.. code-block:: none
%Y-%m-%d %H:%M:%S
@@ -594,7 +610,7 @@ logger, a console handler, and a simple formatter using Python code::
# 'application' code
logger.debug('debug message')
logger.info('info message')
- logger.warn('warn message')
+ logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
@@ -624,11 +640,13 @@ the names of the objects::
# 'application' code
logger.debug('debug message')
logger.info('info message')
- logger.warn('warn message')
+ logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
-Here is the logging.conf file::
+Here is the logging.conf file:
+
+.. code-block:: ini
[loggers]
keys=root,simpleExample
@@ -677,15 +695,15 @@ noncoders to easily modify the logging properties.
.. warning:: The :func:`fileConfig` function takes a default parameter,
``disable_existing_loggers``, which defaults to ``True`` for reasons of
backward compatibility. This may or may not be what you want, since it
- will cause any loggers existing before the :func:`fileConfig` call to
- be disabled unless they (or an ancestor) are explicitly named in the
- configuration. Please refer to the reference documentation for more
+ will cause any non-root loggers existing before the :func:`fileConfig`
+ call to be disabled unless they (or an ancestor) are explicitly named in
+ the configuration. Please refer to the reference documentation for more
information, and specify ``False`` for this parameter if you wish.
The dictionary passed to :func:`dictConfig` can also specify a Boolean
value with key ``disable_existing_loggers``, which if not specified
explicitly in the dictionary also defaults to being interpreted as
- ``True``. This leads to the logger-disabling behaviour described above,
+ ``True``. This leads to the logger-disabling behaviour described above,
which may not be what you want - in which case, provide the key
explicitly with a value of ``False``.
@@ -713,7 +731,9 @@ construct the dictionary in Python code, receive it in pickled form over a
socket, or use whatever approach makes sense for your application.
Here's an example of the same configuration as above, in YAML format for
-the new dictionary-based approach::
+the new dictionary-based approach:
+
+.. code-block:: yaml
version: 1
formatters:
@@ -782,7 +802,7 @@ the best default behaviour.
If for some reason you *don't* want these messages printed in the absence of
any logging configuration, you can attach a do-nothing handler to the top-level
logger for your library. This avoids the message being printed, since a handler
-will be always be found for the library's events: it just doesn't produce any
+will always be found for the library's events: it just doesn't produce any
output. If the library user configures logging for application use, presumably
that configuration will add some handlers, and if levels are suitably
configured then logging calls made in library code will send output to those
@@ -951,7 +971,7 @@ provided:
The :class:`NullHandler`, :class:`StreamHandler` and :class:`FileHandler`
classes are defined in the core logging package. The other handlers are
-defined in a sub- module, :mod:`logging.handlers`. (There is also another
+defined in a sub-module, :mod:`logging.handlers`. (There is also another
sub-module, :mod:`logging.config`, for configuration functionality.)
Logged messages are formatted for presentation through instances of the
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
index 98c81206741a49..8608162bace357 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -119,7 +119,7 @@ Once you have your code well-tested you are ready to begin porting your code to
Python 3! But to fully understand how your code is going to change and what
you want to look out for while you code, you will want to learn what changes
Python 3 makes in terms of Python 2. Typically the two best ways of doing that
-is reading the `"What's New"`_ doc for each release of Python 3 and the
+is reading the :ref:`"What's New" ` doc for each release of Python 3 and the
`Porting to Python 3`_ book (which is free online). There is also a handy
`cheat sheet`_ from the Python-Future project.
@@ -302,10 +302,10 @@ If for some reason that doesn't work then you should make the version check be
against Python 2 and not Python 3. To help explain this, let's look at an
example.
-Let's pretend that you need access to a feature of importlib_ that
+Let's pretend that you need access to a feature of :mod:`importlib` that
is available in Python's standard library since Python 3.3 and available for
Python 2 through importlib2_ on PyPI. You might be tempted to write code to
-access e.g. the ``importlib.abc`` module by doing the following::
+access e.g. the :mod:`importlib.abc` module by doing the following::
import sys
@@ -426,27 +426,23 @@ can also explicitly state whether your APIs use textual or binary data, helping
to make sure everything functions as expected in both versions of Python.
-.. _2to3: https://docs.python.org/3/library/2to3.html
-.. _caniusepython3: https://pypi.python.org/pypi/caniusepython3
+.. _caniusepython3: https://pypi.org/project/caniusepython3
.. _cheat sheet: http://python-future.org/compatible_idioms.html
-.. _coverage.py: https://pypi.python.org/pypi/coverage
+.. _coverage.py: https://pypi.org/project/coverage
.. _Futurize: http://python-future.org/automatic_conversion.html
-.. _importlib: https://docs.python.org/3/library/importlib.html#module-importlib
-.. _importlib2: https://pypi.python.org/pypi/importlib2
+.. _importlib2: https://pypi.org/project/importlib2
.. _Modernize: https://python-modernize.readthedocs.io/
.. _mypy: http://mypy-lang.org/
.. _Porting to Python 3: http://python3porting.com/
-.. _Pylint: https://pypi.python.org/pypi/pylint
+.. _Pylint: https://pypi.org/project/pylint
.. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python3/questions_and_answers.html
.. _pytype: https://github.com/google/pytype
.. _python-future: http://python-future.org/
.. _python-porting: https://mail.python.org/mailman/listinfo/python-porting
-.. _six: https://pypi.python.org/pypi/six
-.. _tox: https://pypi.python.org/pypi/tox
-.. _trove classifier: https://pypi.python.org/pypi?%3Aaction=list_classifiers
-
-.. _"What's New": https://docs.python.org/3/whatsnew/index.html
+.. _six: https://pypi.org/project/six
+.. _tox: https://pypi.org/project/tox
+.. _trove classifier: https://pypi.org/classifiers
.. _Why Python 3 exists: https://snarky.ca/why-python-3-exists
diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst
index 87a6b1aba59f9f..d385d991344b28 100644
--- a/Doc/howto/regex.rst
+++ b/Doc/howto/regex.rst
@@ -96,8 +96,9 @@ special nature.
You can match the characters not listed within the class by :dfn:`complementing`
the set. This is indicated by including a ``'^'`` as the first character of the
-class; ``'^'`` outside a character class will simply match the ``'^'``
-character. For example, ``[^5]`` will match any character except ``'5'``.
+class. For example, ``[^5]`` will match any character except ``'5'``. If the
+caret appears elsewhere in a character class, it does not have special meaning.
+For example: ``[5^]`` will match either a ``'5'`` or a ``'^'``.
Perhaps the most important metacharacter is the backslash, ``\``. As in Python
string literals, the backslash can be followed by various characters to signal
@@ -289,6 +290,8 @@ Putting REs in strings keeps the Python language simpler, but has one
disadvantage which is the topic of the next section.
+.. _the-backslash-plague:
+
The Backslash Plague
--------------------
@@ -327,6 +330,13 @@ backslashes are not handled in any special way in a string literal prefixed with
while ``"\n"`` is a one-character string containing a newline. Regular
expressions will often be written in Python code using this raw string notation.
+In addition, special escape sequences that are valid in regular expressions,
+but not valid as Python string literals, now result in a
+:exc:`DeprecationWarning` and will eventually become a :exc:`SyntaxError`,
+which means the sequences will be invalid if raw string notation or escaping
+the backslashes isn't used.
+
+
+-------------------+------------------+
| Regular String | Raw string |
+===================+==================+
@@ -457,10 +467,16 @@ In actual programs, the most common style is to store the
Two pattern methods return all of the matches for a pattern.
:meth:`~re.Pattern.findall` returns a list of matching strings::
- >>> p = re.compile('\d+')
+ >>> p = re.compile(r'\d+')
>>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
['12', '11', '10']
+The ``r`` prefix, making the literal a raw string literal, is needed in this
+example because escape sequences in a normal "cooked" string literal that are
+not recognized by Python, as opposed to regular expressions, now result in a
+:exc:`DeprecationWarning` and will eventually become a :exc:`SyntaxError`. See
+:ref:`the-backslash-plague`.
+
:meth:`~re.Pattern.findall` has to create the entire list before it can be returned as the
result. The :meth:`~re.Pattern.finditer` method returns a sequence of
:ref:`match object ` instances as an :term:`iterator`::
@@ -771,7 +787,9 @@ Frequently you need to obtain more information than just whether the RE matched
or not. Regular expressions are often used to dissect strings by writing a RE
divided into several subgroups which match different components of interest.
For example, an RFC-822 header line is divided into a header name and a value,
-separated by a ``':'``, like this::
+separated by a ``':'``, like this:
+
+.. code-block:: none
From: author@example.com
User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
@@ -1096,11 +1114,11 @@ following calls::
The module-level function :func:`re.split` adds the RE to be used as the first
argument, but is otherwise the same. ::
- >>> re.split('[\W]+', 'Words, words, words.')
+ >>> re.split(r'[\W]+', 'Words, words, words.')
['Words', 'words', 'words', '']
- >>> re.split('([\W]+)', 'Words, words, words.')
+ >>> re.split(r'([\W]+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
- >>> re.split('[\W]+', 'Words, words, words.', 1)
+ >>> re.split(r'[\W]+', 'Words, words, words.', 1)
['Words', 'words, words.']
diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst
index bc71d85a83e921..b5c2152ec7004d 100644
--- a/Doc/howto/sockets.rst
+++ b/Doc/howto/sockets.rst
@@ -319,7 +319,7 @@ inside-out.
In Python, you use ``socket.setblocking(0)`` to make it non-blocking. In C, it's
more complex, (for one thing, you'll need to choose between the BSD flavor
-``O_NONBLOCK`` and the almost indistinguishable Posix flavor ``O_NDELAY``, which
+``O_NONBLOCK`` and the almost indistinguishable POSIX flavor ``O_NDELAY``, which
is completely different from ``TCP_NODELAY``), but it's the exact same idea. You
do this after creating the socket, but before using it. (Actually, if you're
nuts, you can switch back and forth.)
diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst
index d4b8f8d2204ab7..1ac4102034d33e 100644
--- a/Doc/howto/unicode.rst
+++ b/Doc/howto/unicode.rst
@@ -6,93 +6,48 @@
:Release: 1.12
-This HOWTO discusses Python support for Unicode, and explains
-various problems that people commonly encounter when trying to work
-with Unicode.
+This HOWTO discusses Python's support for the Unicode specification
+for representing textual data, and explains various problems that
+people commonly encounter when trying to work with Unicode.
+
Introduction to Unicode
=======================
-History of Character Codes
---------------------------
-
-In 1968, the American Standard Code for Information Interchange, better known by
-its acronym ASCII, was standardized. ASCII defined numeric codes for various
-characters, with the numeric values running from 0 to 127. For example, the
-lowercase letter 'a' is assigned 97 as its code value.
-
-ASCII was an American-developed standard, so it only defined unaccented
-characters. There was an 'e', but no 'é' or 'Í'. This meant that languages
-which required accented characters couldn't be faithfully represented in ASCII.
-(Actually the missing accents matter for English, too, which contains words such
-as 'naïve' and 'café', and some publications have house styles which require
-spellings such as 'coöperate'.)
-
-For a while people just wrote programs that didn't display accents.
-In the mid-1980s an Apple II BASIC program written by a French speaker
-might have lines like these::
-
- PRINT "MISE A JOUR TERMINEE"
- PRINT "PARAMETRES ENREGISTRES"
-
-Those messages should contain accents (terminée, paramètre, enregistrés) and
-they just look wrong to someone who can read French.
-
-In the 1980s, almost all personal computers were 8-bit, meaning that bytes could
-hold values ranging from 0 to 255. ASCII codes only went up to 127, so some
-machines assigned values between 128 and 255 to accented characters. Different
-machines had different codes, however, which led to problems exchanging files.
-Eventually various commonly used sets of values for the 128--255 range emerged.
-Some were true standards, defined by the International Organization for
-Standardization, and some were *de facto* conventions that were invented by one
-company or another and managed to catch on.
-
-255 characters aren't very many. For example, you can't fit both the accented
-characters used in Western Europe and the Cyrillic alphabet used for Russian
-into the 128--255 range because there are more than 128 such characters.
-
-You could write files using different codes (all your Russian files in a coding
-system called KOI8, all your French files in a different coding system called
-Latin1), but what if you wanted to write a French document that quotes some
-Russian text? In the 1980s people began to want to solve this problem, and the
-Unicode standardization effort began.
-
-Unicode started out using 16-bit characters instead of 8-bit characters. 16
-bits means you have 2^16 = 65,536 distinct values available, making it possible
-to represent many different characters from many different alphabets; an initial
-goal was to have Unicode contain the alphabets for every single human language.
-It turns out that even 16 bits isn't enough to meet that goal, and the modern
-Unicode specification uses a wider range of codes, 0 through 1,114,111 (
-``0x10FFFF`` in base 16).
-
-There's a related ISO standard, ISO 10646. Unicode and ISO 10646 were
-originally separate efforts, but the specifications were merged with the 1.1
-revision of Unicode.
-
-(This discussion of Unicode's history is highly simplified. The
-precise historical details aren't necessary for understanding how to
-use Unicode effectively, but if you're curious, consult the Unicode
-consortium site listed in the References or
-the `Wikipedia entry for Unicode `_
-for more information.)
-
-
Definitions
-----------
+Today's programs need to be able to handle a wide variety of
+characters. Applications are often internationalized to display
+messages and output in a variety of user-selectable languages; the
+same program might need to output an error message in English, French,
+Japanese, Hebrew, or Russian. Web content can be written in any of
+these languages and can also include a variety of emoji symbols.
+Python's string type uses the Unicode Standard for representing
+characters, which lets Python programs work with all these different
+possible characters.
+
+Unicode (https://www.unicode.org/) is a specification that aims to
+list every character used by human languages and give each character
+its own unique code. The Unicode specifications are continually
+revised and updated to add new languages and symbols.
+
A **character** is the smallest possible component of a text. 'A', 'B', 'C',
-etc., are all different characters. So are 'È' and 'Í'. Characters are
-abstractions, and vary depending on the language or context you're talking
-about. For example, the symbol for ohms (Ω) is usually drawn much like the
-capital letter omega (Ω) in the Greek alphabet (they may even be the same in
-some fonts), but these are two different characters that have different
-meanings.
-
-The Unicode standard describes how characters are represented by **code
-points**. A code point is an integer value, usually denoted in base 16. In the
-standard, a code point is written using the notation ``U+12CA`` to mean the
-character with value ``0x12ca`` (4,810 decimal). The Unicode standard contains
-a lot of tables listing characters and their corresponding code points:
+etc., are all different characters. So are 'È' and 'Í'. Characters vary
+depending on the language or context you're talking
+about. For example, there's a character for "Roman Numeral One", 'Ⅰ', that's
+separate from the uppercase letter 'I'. They'll usually look the same,
+but these are two different characters that have different meanings.
+
+The Unicode standard describes how characters are represented by
+**code points**. A code point value is an integer in the range 0 to
+0x10FFFF (about 1.1 million values, with some 110 thousand assigned so
+far). In the standard and in this document, a code point is written
+using the notation ``U+265E`` to mean the character with value
+``0x265e`` (9,822 in decimal).
+
+The Unicode standard contains a lot of tables listing characters and
+their corresponding code points:
.. code-block:: none
@@ -101,10 +56,21 @@ a lot of tables listing characters and their corresponding code points:
0063 'c'; LATIN SMALL LETTER C
...
007B '{'; LEFT CURLY BRACKET
+ ...
+ 2167 'Ⅷ'; ROMAN NUMERAL EIGHT
+ 2168 'Ⅸ'; ROMAN NUMERAL NINE
+ ...
+ 265E '♞'; BLACK CHESS KNIGHT
+ 265F '♟'; BLACK CHESS PAWN
+ ...
+ 1F600 '😀'; GRINNING FACE
+ 1F609 '😉'; WINKING FACE
+ ...
Strictly, these definitions imply that it's meaningless to say 'this is
-character ``U+12CA``'. ``U+12CA`` is a code point, which represents some particular
-character; in this case, it represents the character 'ETHIOPIC SYLLABLE WI'. In
+character ``U+265E``'. ``U+265E`` is a code point, which represents some particular
+character; in this case, it represents the character 'BLACK CHESS KNIGHT',
+'♞'. In
informal contexts, this distinction between code points and characters will
sometimes be forgotten.
@@ -119,14 +85,17 @@ toolkit or a terminal's font renderer.
Encodings
---------
-To summarize the previous section: a Unicode string is a sequence of code
-points, which are numbers from 0 through ``0x10FFFF`` (1,114,111 decimal). This
-sequence needs to be represented as a set of bytes (meaning, values
-from 0 through 255) in memory. The rules for translating a Unicode string
-into a sequence of bytes are called an **encoding**.
+To summarize the previous section: a Unicode string is a sequence of
+code points, which are numbers from 0 through ``0x10FFFF`` (1,114,111
+decimal). This sequence of code points needs to be represented in
+memory as a set of **code units**, and **code units** are then mapped
+to 8-bit bytes. The rules for translating a Unicode string into a
+sequence of bytes are called a **character encoding**, or just
+an **encoding**.
-The first encoding you might think of is an array of 32-bit integers. In this
-representation, the string "Python" would look like this:
+The first encoding you might think of is using 32-bit integers as the
+code unit, and then using the CPU's representation of 32-bit integers.
+In this representation, the string "Python" might look like this:
.. code-block:: none
@@ -150,40 +119,14 @@ problems.
3. It's not compatible with existing C functions such as ``strlen()``, so a new
family of wide string functions would need to be used.
-4. Many Internet standards are defined in terms of textual data, and can't
- handle content with embedded zero bytes.
-
-Generally people don't use this encoding, instead choosing other
-encodings that are more efficient and convenient. UTF-8 is probably
-the most commonly supported encoding; it will be discussed below.
-
-Encodings don't have to handle every possible Unicode character, and most
-encodings don't. The rules for converting a Unicode string into the ASCII
-encoding, for example, are simple; for each code point:
-
-1. If the code point is < 128, each byte is the same as the value of the code
- point.
-
-2. If the code point is 128 or greater, the Unicode string can't be represented
- in this encoding. (Python raises a :exc:`UnicodeEncodeError` exception in this
- case.)
+Therefore this encoding isn't used very much, and people instead choose other
+encodings that are more efficient and convenient, such as UTF-8.
-Latin-1, also known as ISO-8859-1, is a similar encoding. Unicode code points
-0--255 are identical to the Latin-1 values, so converting to this encoding simply
-requires converting code points to byte values; if a code point larger than 255
-is encountered, the string can't be encoded into Latin-1.
-
-Encodings don't have to be simple one-to-one mappings like Latin-1. Consider
-IBM's EBCDIC, which was used on IBM mainframes. Letter values weren't in one
-block: 'a' through 'i' had values from 129 to 137, but 'j' through 'r' were 145
-through 153. If you wanted to use EBCDIC as an encoding, you'd probably use
-some sort of lookup table to perform the conversion, but this is largely an
-internal detail.
-
-UTF-8 is one of the most commonly used encodings. UTF stands for "Unicode
-Transformation Format", and the '8' means that 8-bit numbers are used in the
-encoding. (There are also a UTF-16 and UTF-32 encodings, but they are less
-frequently used than UTF-8.) UTF-8 uses the following rules:
+UTF-8 is one of the most commonly used encodings, and Python often
+defaults to using it. UTF stands for "Unicode Transformation Format",
+and the '8' means that 8-bit values are used in the encoding. (There
+are also UTF-16 and UTF-32 encodings, but they are less frequently
+used than UTF-8.) UTF-8 uses the following rules:
1. If the code point is < 128, it's represented by the corresponding byte value.
2. If the code point is >= 128, it's turned into a sequence of two, three, or
@@ -192,17 +135,22 @@ frequently used than UTF-8.) UTF-8 uses the following rules:
UTF-8 has several convenient properties:
1. It can handle any Unicode code point.
-2. A Unicode string is turned into a sequence of bytes containing no embedded zero
- bytes. This avoids byte-ordering issues, and means UTF-8 strings can be
- processed by C functions such as ``strcpy()`` and sent through protocols that
- can't handle zero bytes.
+2. A Unicode string is turned into a sequence of bytes that contains embedded
+ zero bytes only where they represent the null character (U+0000). This means
+ that UTF-8 strings can be processed by C functions such as ``strcpy()`` and sent
+ through protocols that can't handle zero bytes for anything other than
+ end-of-string markers.
3. A string of ASCII text is also valid UTF-8 text.
4. UTF-8 is fairly compact; the majority of commonly used characters can be
represented with one or two bytes.
5. If bytes are corrupted or lost, it's possible to determine the start of the
next UTF-8-encoded code point and resynchronize. It's also unlikely that
random 8-bit data will look like valid UTF-8.
-
+6. UTF-8 is a byte oriented encoding. The encoding specifies that each
+ character is represented by a specific sequence of one or more bytes. This
+ avoids the byte-ordering issues that can occur with integer and word oriented
+ encodings, like UTF-16 and UTF-32, where the sequence of bytes varies depending
+ on the hardware on which the string was encoded.
References
@@ -213,6 +161,10 @@ glossary, and PDF versions of the Unicode specification. Be prepared for some
difficult reading. `A chronology `_ of the
origin and development of Unicode is also available on the site.
+On the Computerphile Youtube channel, Tom Scott briefly
+`discusses the history of Unicode and UTF-8 `
+(9 minutes 36 seconds).
+
To help understand the standard, Jukka Korpela has written `an introductory
guide `_ to reading the
Unicode character tables.
@@ -236,7 +188,7 @@ Unicode features.
The String Type
---------------
-Since Python 3.0, the language features a :class:`str` type that contain Unicode
+Since Python 3.0, the language's :class:`str` type contains Unicode
characters, meaning any string created using ``"unicode rocks!"``, ``'unicode
rocks!'``, or the triple-quoted string syntax is stored as Unicode.
@@ -250,11 +202,6 @@ include a Unicode character in a string literal::
# 'File not found' error message.
print("Fichier non trouvé")
-You can use a different encoding from UTF-8 by putting a specially-formatted
-comment as the first or second line of the source code::
-
- # -*- coding: -*-
-
Side note: Python 3 also supports using Unicode characters in identifiers::
répertoire = "/tmp/records.log"
@@ -297,7 +244,7 @@ The following examples show the differences::
>>> b'\x80abc'.decode("utf-8", "ignore")
'abc'
-Encodings are specified as strings containing the encoding's name. Python 3.2
+Encodings are specified as strings containing the encoding's name. Python
comes with roughly 100 different encodings; see the Python Library Reference at
:ref:`standard-encodings` for a list. Some encodings have multiple names; for
example, ``'latin-1'``, ``'iso_8859_1'`` and ``'8859``' are all synonyms for
@@ -407,12 +354,13 @@ already mentioned. See also :pep:`263` for more information.
Unicode Properties
------------------
-The Unicode specification includes a database of information about code points.
-For each defined code point, the information includes the character's
-name, its category, the numeric value if applicable (Unicode has characters
-representing the Roman numerals and fractions such as one-third and
-four-fifths). There are also properties related to the code point's use in
-bidirectional text and other display-related properties.
+The Unicode specification includes a database of information about
+code points. For each defined code point, the information includes
+the character's name, its category, the numeric value if applicable
+(for characters representing numeric concepts such as the Roman
+numerals, fractions such as one-third and four-fifths, etc.). There
+are also display-related properties, such as how to use the code point
+in bidirectional text.
The following program displays some information about several characters, and
prints the numeric value of one particular character::
@@ -449,6 +397,88 @@ other". See
list of category codes.
+Comparing Strings
+-----------------
+
+Unicode adds some complication to comparing strings, because the same
+set of characters can be represented by different sequences of code
+points. For example, a letter like 'ê' can be represented as a single
+code point U+00EA, or as U+0065 U+0302, which is the code point for
+'e' followed by a code point for 'COMBINING CIRCUMFLEX ACCENT'. These
+will produce the same output when printed, but one is a string of
+length 1 and the other is of length 2.
+
+One tool for a case-insensitive comparison is the
+:meth:`~str.casefold` string method that converts a string to a
+case-insensitive form following an algorithm described by the Unicode
+Standard. This algorithm has special handling for characters such as
+the German letter 'ß' (code point U+00DF), which becomes the pair of
+lowercase letters 'ss'.
+
+::
+
+ >>> street = 'Gürzenichstraße'
+ >>> street.casefold()
+ 'gürzenichstrasse'
+
+A second tool is the :mod:`unicodedata` module's
+:func:`~unicodedata.normalize` function that converts strings to one
+of several normal forms, where letters followed by a combining
+character are replaced with single characters. :func:`normalize` can
+be used to perform string comparisons that won't falsely report
+inequality if two strings use combining characters differently:
+
+::
+
+ import unicodedata
+
+ def compare_strs(s1, s2):
+ def NFD(s):
+ return unicodedata.normalize('NFD', s)
+
+ return NFD(s1) == NFD(s2)
+
+ single_char = 'ê'
+ multiple_chars = '\N{LATIN SMALL LETTER E}\N{COMBINING CIRCUMFLEX ACCENT}'
+ print('length of first string=', len(single_char))
+ print('length of second string=', len(multiple_chars))
+ print(compare_strs(single_char, multiple_chars))
+
+When run, this outputs:
+
+.. code-block:: shell-session
+
+ $ python3 compare-strs.py
+ length of first string= 1
+ length of second string= 2
+ True
+
+The first argument to the :func:`~unicodedata.normalize` function is a
+string giving the desired normalization form, which can be one of
+'NFC', 'NFKC', 'NFD', and 'NFKD'.
+
+The Unicode Standard also specifies how to do caseless comparisons::
+
+ import unicodedata
+
+ def compare_caseless(s1, s2):
+ def NFD(s):
+ return unicodedata.normalize('NFD', s)
+
+ return NFD(NFD(s1).casefold()) == NFD(NFD(s2).casefold())
+
+ # Example usage
+ single_char = 'ê'
+ multiple_chars = '\N{LATIN CAPITAL LETTER E}\N{COMBINING CIRCUMFLEX ACCENT}'
+
+ print(compare_caseless(single_char, multiple_chars))
+
+This will print ``True``. (Why is :func:`NFD` invoked twice? Because
+there are a few characters that make :meth:`casefold` return a
+non-normalized string, so the result needs to be normalized again. See
+section 3.13 of the Unicode Standard for a discussion and an example.)
+
+
Unicode Regular Expressions
---------------------------
@@ -463,7 +493,7 @@ The string in this example has the number 57 written in both Thai and
Arabic numerals::
import re
- p = re.compile('\d+')
+ p = re.compile(r'\d+')
s = "Over \u0e55\u0e57 57 flavours"
m = p.search(s)
@@ -565,22 +595,22 @@ particular byte ordering and don't skip the BOM.
In some areas, it is also convention to use a "BOM" at the start of UTF-8
encoded files; the name is misleading since UTF-8 is not byte-order dependent.
-The mark simply announces that the file is encoded in UTF-8. Use the
-'utf-8-sig' codec to automatically skip the mark if present for reading such
-files.
+The mark simply announces that the file is encoded in UTF-8. For reading such
+files, use the 'utf-8-sig' codec to automatically skip the mark if present.
Unicode filenames
-----------------
-Most of the operating systems in common use today support filenames that contain
-arbitrary Unicode characters. Usually this is implemented by converting the
-Unicode string into some encoding that varies depending on the system. For
-example, Mac OS X uses UTF-8 while Windows uses a configurable encoding; on
-Windows, Python uses the name "mbcs" to refer to whatever the currently
-configured encoding is. On Unix systems, there will only be a filesystem
-encoding if you've set the ``LANG`` or ``LC_CTYPE`` environment variables; if
-you haven't, the default encoding is UTF-8.
+Most of the operating systems in common use today support filenames
+that contain arbitrary Unicode characters. Usually this is
+implemented by converting the Unicode string into some encoding that
+varies depending on the system. Today Python is converging on using
+UTF-8: Python on MacOS has used UTF-8 for several versions, and Python
+3.6 switched to using UTF-8 on Windows as well. On Unix systems,
+there will only be a filesystem encoding if you've set the ``LANG`` or
+``LC_CTYPE`` environment variables; if you haven't, the default
+encoding is again UTF-8.
The :func:`sys.getfilesystemencoding` function returns the encoding to use on
your current system, in case you want to do the encoding manually, but there's
@@ -595,9 +625,9 @@ automatically converted to the right encoding for you::
Functions in the :mod:`os` module such as :func:`os.stat` will also accept Unicode
filenames.
-The :func:`os.listdir` function returns filenames and raises an issue: should it return
+The :func:`os.listdir` function returns filenames, which raises an issue: should it return
the Unicode version of filenames, or should it return bytes containing
-the encoded versions? :func:`os.listdir` will do both, depending on whether you
+the encoded versions? :func:`os.listdir` can do both, depending on whether you
provided the directory path as bytes or a Unicode string. If you pass a
Unicode string as the path, filenames will be decoded using the filesystem's
encoding and a list of Unicode strings will be returned, while passing a byte
@@ -617,16 +647,17 @@ will produce the following output:
.. code-block:: shell-session
- amk:~$ python t.py
+ $ python listdir-test.py
[b'filename\xe4\x94\x80abc', ...]
['filename\u4500abc', ...]
The first list contains UTF-8-encoded filenames, and the second list contains
the Unicode versions.
-Note that on most occasions, the Unicode APIs should be used. The bytes APIs
-should only be used on systems where undecodable file names can be present,
-i.e. Unix systems.
+Note that on most occasions, you should can just stick with using
+Unicode with these APIs. The bytes APIs should only be used on
+systems where undecodable file names can be present; that's
+pretty much only Unix systems now.
Tips for Writing Unicode-aware Programs
@@ -693,10 +724,10 @@ with the ``surrogateescape`` error handler::
f.write(data)
The ``surrogateescape`` error handler will decode any non-ASCII bytes
-as code points in the Unicode Private Use Area ranging from U+DC80 to
-U+DCFF. These private code points will then be turned back into the
-same bytes when the ``surrogateescape`` error handler is used when
-encoding the data and writing it back out.
+as code points in a special range running from U+DC80 to
+U+DCFF. These code points will then turn back into the
+same bytes when the ``surrogateescape`` error handler is used to
+encode the data and write it back out.
References
@@ -728,4 +759,5 @@ Andrew Kuchling, and Ezio Melotti.
Thanks to the following people who have noted errors or offered
suggestions on this article: Éric Araujo, Nicholas Bastin, Nick
Coghlan, Marius Gedminas, Kent Johnson, Ken Krugler, Marc-André
-Lemburg, Martin von Löwis, Terry J. Reedy, Chad Whitacre.
+Lemburg, Martin von Löwis, Terry J. Reedy, Serhiy Storchaka,
+Eryk Sun, Chad Whitacre, Graham Wideman.
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index c1fd5cf0680d96..046a88af62f0b3 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -56,12 +56,20 @@ The simplest way to use urllib.request is as follows::
with urllib.request.urlopen('http://python.org/') as response:
html = response.read()
-If you wish to retrieve a resource via URL and store it in a temporary location,
-you can do so via the :func:`~urllib.request.urlretrieve` function::
+If you wish to retrieve a resource via URL and store it in a temporary
+location, you can do so via the :func:`shutil.copyfileobj` and
+:func:`tempfile.NamedTemporaryFile` functions::
+ import shutil
+ import tempfile
import urllib.request
- local_filename, headers = urllib.request.urlretrieve('http://python.org/')
- html = open(local_filename)
+
+ with urllib.request.urlopen('http://python.org/') as response:
+ with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
+ shutil.copyfileobj(response, tmp_file)
+
+ with open(tmp_file.name) as html:
+ pass
Many uses of urllib will be that simple (note that instead of an 'http:' URL we
could have used a URL starting with 'ftp:', 'file:', etc.). However, it's the
@@ -231,7 +239,7 @@ a different URL, urllib will handle that for you). For those it can't handle,
urlopen will raise an :exc:`HTTPError`. Typical errors include '404' (page not
found), '403' (request forbidden), and '401' (authentication required).
-See section 10 of RFC 2616 for a reference on all the HTTP error codes.
+See section 10 of :rfc:`2616` for a reference on all the HTTP error codes.
The :exc:`HTTPError` instance raised will have an integer 'code' attribute, which
corresponds to the error sent by the server.
@@ -244,7 +252,7 @@ codes in the 100--299 range indicate success, you will usually only see error
codes in the 400--599 range.
:attr:`http.server.BaseHTTPRequestHandler.responses` is a useful dictionary of
-response codes in that shows all the response codes used by RFC 2616. The
+response codes in that shows all the response codes used by :rfc:`2616`. The
dictionary is reproduced here for convenience ::
# Table mapping response codes to messages; entries have the
@@ -457,7 +465,9 @@ error code) requesting authentication. This specifies the authentication scheme
and a 'realm'. The header looks like: ``WWW-Authenticate: SCHEME
realm="REALM"``.
-e.g. ::
+e.g.
+
+.. code-block:: none
WWW-Authenticate: Basic realm="cPanel Users"
diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c
new file mode 100644
index 00000000000000..f361baf830dd1b
--- /dev/null
+++ b/Doc/includes/custom.c
@@ -0,0 +1,45 @@
+#define PY_SSIZE_T_CLEAN
+#include
+
+typedef struct {
+ PyObject_HEAD
+ /* Type-specific fields go here. */
+} CustomObject;
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_new = PyType_GenericNew,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
+ return m;
+}
diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c
new file mode 100644
index 00000000000000..5bacab7a2a9714
--- /dev/null
+++ b/Doc/includes/custom2.c
@@ -0,0 +1,138 @@
+#define PY_SSIZE_T_CLEAN
+#include
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+} CustomObject;
+
+static void
+Custom_dealloc(CustomObject *self)
+{
+ Py_XDECREF(self->first);
+ Py_XDECREF(self->last);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static PyObject *
+Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+}
+
+static int
+Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_XDECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_XDECREF(tmp);
+ }
+ return 0;
+}
+
+static PyMemberDef Custom_members[] = {
+ {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0,
+ "first name"},
+ {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0,
+ "last name"},
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
+{
+ if (self->first == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "first");
+ return NULL;
+ }
+ if (self->last == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "last");
+ return NULL;
+ }
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+}
+
+static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom2.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = Custom_new,
+ .tp_init = (initproc) Custom_init,
+ .tp_dealloc = (destructor) Custom_dealloc,
+ .tp_members = Custom_members,
+ .tp_methods = Custom_methods,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom2",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom2(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
+ return m;
+}
diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c
new file mode 100644
index 00000000000000..2b7a99ecf96c76
--- /dev/null
+++ b/Doc/includes/custom3.c
@@ -0,0 +1,189 @@
+#define PY_SSIZE_T_CLEAN
+#include
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+} CustomObject;
+
+static void
+Custom_dealloc(CustomObject *self)
+{
+ Py_XDECREF(self->first);
+ Py_XDECREF(self->last);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static PyObject *
+Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+}
+
+static int
+Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_DECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_DECREF(tmp);
+ }
+ return 0;
+}
+
+static PyMemberDef Custom_members[] = {
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_getfirst(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->first);
+ return self->first;
+}
+
+static int
+Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
+{
+ PyObject *tmp;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a string");
+ return -1;
+ }
+ tmp = self->first;
+ Py_INCREF(value);
+ self->first = value;
+ Py_DECREF(tmp);
+ return 0;
+}
+
+static PyObject *
+Custom_getlast(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->last);
+ return self->last;
+}
+
+static int
+Custom_setlast(CustomObject *self, PyObject *value, void *closure)
+{
+ PyObject *tmp;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The last attribute value must be a string");
+ return -1;
+ }
+ tmp = self->last;
+ Py_INCREF(value);
+ self->last = value;
+ Py_DECREF(tmp);
+ return 0;
+}
+
+static PyGetSetDef Custom_getsetters[] = {
+ {"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
+ "first name", NULL},
+ {"last", (getter) Custom_getlast, (setter) Custom_setlast,
+ "last name", NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+}
+
+static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom3.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = Custom_new,
+ .tp_init = (initproc) Custom_init,
+ .tp_dealloc = (destructor) Custom_dealloc,
+ .tp_members = Custom_members,
+ .tp_methods = Custom_methods,
+ .tp_getset = Custom_getsetters,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom3",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom3(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
+ return m;
+}
diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c
new file mode 100644
index 00000000000000..584992fc5f1a8a
--- /dev/null
+++ b/Doc/includes/custom4.c
@@ -0,0 +1,203 @@
+#define PY_SSIZE_T_CLEAN
+#include
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+} CustomObject;
+
+static int
+Custom_traverse(CustomObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->first);
+ Py_VISIT(self->last);
+ return 0;
+}
+
+static int
+Custom_clear(CustomObject *self)
+{
+ Py_CLEAR(self->first);
+ Py_CLEAR(self->last);
+ return 0;
+}
+
+static void
+Custom_dealloc(CustomObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ Custom_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static PyObject *
+Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+}
+
+static int
+Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_DECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_DECREF(tmp);
+ }
+ return 0;
+}
+
+static PyMemberDef Custom_members[] = {
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_getfirst(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->first);
+ return self->first;
+}
+
+static int
+Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
+{
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a string");
+ return -1;
+ }
+ Py_INCREF(value);
+ Py_CLEAR(self->first);
+ self->first = value;
+ return 0;
+}
+
+static PyObject *
+Custom_getlast(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->last);
+ return self->last;
+}
+
+static int
+Custom_setlast(CustomObject *self, PyObject *value, void *closure)
+{
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The last attribute value must be a string");
+ return -1;
+ }
+ Py_INCREF(value);
+ Py_CLEAR(self->last);
+ self->last = value;
+ return 0;
+}
+
+static PyGetSetDef Custom_getsetters[] = {
+ {"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
+ "first name", NULL},
+ {"last", (getter) Custom_getlast, (setter) Custom_setlast,
+ "last name", NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+}
+
+static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom4.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ .tp_new = Custom_new,
+ .tp_init = (initproc) Custom_init,
+ .tp_dealloc = (destructor) Custom_dealloc,
+ .tp_traverse = (traverseproc) Custom_traverse,
+ .tp_clear = (inquiry) Custom_clear,
+ .tp_members = Custom_members,
+ .tp_methods = Custom_methods,
+ .tp_getset = Custom_getsetters,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom4",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom4(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
+ return m;
+}
diff --git a/Doc/includes/email-dir.py b/Doc/includes/email-dir.py
index 0dcfbfb4025c85..2fc1570e654db6 100644
--- a/Doc/includes/email-dir.py
+++ b/Doc/includes/email-dir.py
@@ -41,7 +41,7 @@ def main():
directory = '.'
# Create the message
msg = EmailMessage()
- msg['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)
+ msg['Subject'] = f'Contents of directory {os.path.abspath(directory)}'
msg['To'] = ', '.join(args.recipients)
msg['From'] = args.sender
msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
diff --git a/Doc/includes/email-mime.py b/Doc/includes/email-mime.py
index c610242f11f843..6af2be0b08a48d 100644
--- a/Doc/includes/email-mime.py
+++ b/Doc/includes/email-mime.py
@@ -14,7 +14,7 @@
# family = the list of all recipients' email addresses
msg['From'] = me
msg['To'] = ', '.join(family)
-msg.preamble = 'Our family reunion'
+msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
# Open the files in binary mode. Use imghdr to figure out the
# MIME subtype for each specific image.
diff --git a/Doc/includes/email-simple.py b/Doc/includes/email-simple.py
index f69ef40ff04c93..07dc30fd066eac 100644
--- a/Doc/includes/email-simple.py
+++ b/Doc/includes/email-simple.py
@@ -12,7 +12,7 @@
# me == the sender's email address
# you == the recipient's email address
-msg['Subject'] = 'The contents of %s' % textfile
+msg['Subject'] = f'The contents of {textfile}'
msg['From'] = me
msg['To'] = you
diff --git a/Doc/includes/email-unpack.py b/Doc/includes/email-unpack.py
index e0a7f01f58bb59..c8cb0be4560830 100644
--- a/Doc/includes/email-unpack.py
+++ b/Doc/includes/email-unpack.py
@@ -43,7 +43,7 @@ def main():
if not ext:
# Use a generic bag-of-bits extension
ext = '.bin'
- filename = 'part-%03d%s' % (counter, ext)
+ filename = f'part-{counter:03d}{ext}'
counter += 1
with open(os.path.join(args.directory, filename), 'wb') as fp:
fp.write(part.get_payload(decode=True))
diff --git a/Doc/includes/noddy.c b/Doc/includes/noddy.c
deleted file mode 100644
index 07b5d5a9b83ce0..00000000000000
--- a/Doc/includes/noddy.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include
-
-typedef struct {
- PyObject_HEAD
- /* Type-specific fields go here. */
-} noddy_NoddyObject;
-
-static PyTypeObject noddy_NoddyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "noddy.Noddy", /* tp_name */
- sizeof(noddy_NoddyObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- "Noddy objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
-};
-
-static PyModuleDef noddymodule = {
- PyModuleDef_HEAD_INIT,
- "noddy",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy(void)
-{
- PyObject* m;
-
- if (PyType_Ready(&noddy_NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddymodule);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&noddy_NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
- return m;
-}
diff --git a/Doc/includes/noddy2.c b/Doc/includes/noddy2.c
deleted file mode 100644
index 964155845fee83..00000000000000
--- a/Doc/includes/noddy2.c
+++ /dev/null
@@ -1,172 +0,0 @@
-#include
-#include "structmember.h"
-
-typedef struct {
- PyObject_HEAD
- PyObject *first; /* first name */
- PyObject *last; /* last name */
- int number;
-} Noddy;
-
-static void
-Noddy_dealloc(Noddy* self)
-{
- Py_XDECREF(self->first);
- Py_XDECREF(self->last);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
-}
-
-static int
-Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
-{
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_XDECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_XDECREF(tmp);
- }
-
- return 0;
-}
-
-
-static PyMemberDef Noddy_members[] = {
- {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
- "first name"},
- {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
- "last name"},
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_name(Noddy* self)
-{
- if (self->first == NULL) {
- PyErr_SetString(PyExc_AttributeError, "first");
- return NULL;
- }
-
- if (self->last == NULL) {
- PyErr_SetString(PyExc_AttributeError, "last");
- return NULL;
- }
-
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
-}
-
-static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NoddyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "noddy.Noddy", /* tp_name */
- sizeof(Noddy), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Noddy_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
- "Noddy objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Noddy_methods, /* tp_methods */
- Noddy_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Noddy_init, /* tp_init */
- 0, /* tp_alloc */
- Noddy_new, /* tp_new */
-};
-
-static PyModuleDef noddy2module = {
- PyModuleDef_HEAD_INIT,
- "noddy2",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy2(void)
-{
- PyObject* m;
-
- if (PyType_Ready(&NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddy2module);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
- return m;
-}
diff --git a/Doc/includes/noddy3.c b/Doc/includes/noddy3.c
deleted file mode 100644
index 8a5a753ca439eb..00000000000000
--- a/Doc/includes/noddy3.c
+++ /dev/null
@@ -1,225 +0,0 @@
-#include
-#include "structmember.h"
-
-typedef struct {
- PyObject_HEAD
- PyObject *first;
- PyObject *last;
- int number;
-} Noddy;
-
-static void
-Noddy_dealloc(Noddy* self)
-{
- Py_XDECREF(self->first);
- Py_XDECREF(self->last);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
-}
-
-static int
-Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
-{
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_DECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_DECREF(tmp);
- }
-
- return 0;
-}
-
-static PyMemberDef Noddy_members[] = {
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_getfirst(Noddy *self, void *closure)
-{
- Py_INCREF(self->first);
- return self->first;
-}
-
-static int
-Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
-{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
- return -1;
- }
-
- if (! PyUnicode_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The first attribute value must be a string");
- return -1;
- }
-
- Py_DECREF(self->first);
- Py_INCREF(value);
- self->first = value;
-
- return 0;
-}
-
-static PyObject *
-Noddy_getlast(Noddy *self, void *closure)
-{
- Py_INCREF(self->last);
- return self->last;
-}
-
-static int
-Noddy_setlast(Noddy *self, PyObject *value, void *closure)
-{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
- return -1;
- }
-
- if (! PyUnicode_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The last attribute value must be a string");
- return -1;
- }
-
- Py_DECREF(self->last);
- Py_INCREF(value);
- self->last = value;
-
- return 0;
-}
-
-static PyGetSetDef Noddy_getseters[] = {
- {"first",
- (getter)Noddy_getfirst, (setter)Noddy_setfirst,
- "first name",
- NULL},
- {"last",
- (getter)Noddy_getlast, (setter)Noddy_setlast,
- "last name",
- NULL},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_name(Noddy* self)
-{
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
-}
-
-static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NoddyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "noddy.Noddy", /* tp_name */
- sizeof(Noddy), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Noddy_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
- "Noddy objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Noddy_methods, /* tp_methods */
- Noddy_members, /* tp_members */
- Noddy_getseters, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Noddy_init, /* tp_init */
- 0, /* tp_alloc */
- Noddy_new, /* tp_new */
-};
-
-static PyModuleDef noddy3module = {
- PyModuleDef_HEAD_INIT,
- "noddy3",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy3(void)
-{
- PyObject* m;
-
- if (PyType_Ready(&NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddy3module);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
- return m;
-}
diff --git a/Doc/includes/noddy4.c b/Doc/includes/noddy4.c
deleted file mode 100644
index 08ba4c3d91a030..00000000000000
--- a/Doc/includes/noddy4.c
+++ /dev/null
@@ -1,208 +0,0 @@
-#include
-#include "structmember.h"
-
-typedef struct {
- PyObject_HEAD
- PyObject *first;
- PyObject *last;
- int number;
-} Noddy;
-
-static int
-Noddy_traverse(Noddy *self, visitproc visit, void *arg)
-{
- int vret;
-
- if (self->first) {
- vret = visit(self->first, arg);
- if (vret != 0)
- return vret;
- }
- if (self->last) {
- vret = visit(self->last, arg);
- if (vret != 0)
- return vret;
- }
-
- return 0;
-}
-
-static int
-Noddy_clear(Noddy *self)
-{
- PyObject *tmp;
-
- tmp = self->first;
- self->first = NULL;
- Py_XDECREF(tmp);
-
- tmp = self->last;
- self->last = NULL;
- Py_XDECREF(tmp);
-
- return 0;
-}
-
-static void
-Noddy_dealloc(Noddy* self)
-{
- PyObject_GC_UnTrack(self);
- Noddy_clear(self);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
-}
-
-static int
-Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
-{
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_XDECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_XDECREF(tmp);
- }
-
- return 0;
-}
-
-
-static PyMemberDef Noddy_members[] = {
- {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
- "first name"},
- {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
- "last name"},
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_name(Noddy* self)
-{
- if (self->first == NULL) {
- PyErr_SetString(PyExc_AttributeError, "first");
- return NULL;
- }
-
- if (self->last == NULL) {
- PyErr_SetString(PyExc_AttributeError, "last");
- return NULL;
- }
-
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
-}
-
-static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NoddyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "noddy.Noddy", /* tp_name */
- sizeof(Noddy), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Noddy_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT |
- Py_TPFLAGS_BASETYPE |
- Py_TPFLAGS_HAVE_GC, /* tp_flags */
- "Noddy objects", /* tp_doc */
- (traverseproc)Noddy_traverse, /* tp_traverse */
- (inquiry)Noddy_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Noddy_methods, /* tp_methods */
- Noddy_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Noddy_init, /* tp_init */
- 0, /* tp_alloc */
- Noddy_new, /* tp_new */
-};
-
-static PyModuleDef noddy4module = {
- PyModuleDef_HEAD_INIT,
- "noddy4",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy4(void)
-{
- PyObject* m;
-
- if (PyType_Ready(&NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddy4module);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
- return m;
-}
diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c
index ead7bdd23209a3..392f86d65ecc17 100644
--- a/Doc/includes/run-func.c
+++ b/Doc/includes/run-func.c
@@ -1,9 +1,10 @@
+#define PY_SSIZE_T_CLEAN
#include
int
main(int argc, char *argv[])
{
- PyObject *pName, *pModule, *pDict, *pFunc;
+ PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
int i;
diff --git a/Doc/includes/shoddy.c b/Doc/includes/shoddy.c
deleted file mode 100644
index 0ef4765327776f..00000000000000
--- a/Doc/includes/shoddy.c
+++ /dev/null
@@ -1,99 +0,0 @@
-#include
-
-typedef struct {
- PyListObject list;
- int state;
-} Shoddy;
-
-
-static PyObject *
-Shoddy_increment(Shoddy *self, PyObject *unused)
-{
- self->state++;
- return PyLong_FromLong(self->state);
-}
-
-
-static PyMethodDef Shoddy_methods[] = {
- {"increment", (PyCFunction)Shoddy_increment, METH_NOARGS,
- PyDoc_STR("increment state counter")},
- {NULL},
-};
-
-static int
-Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
-{
- if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
- return -1;
- self->state = 0;
- return 0;
-}
-
-
-static PyTypeObject ShoddyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "shoddy.Shoddy", /* tp_name */
- sizeof(Shoddy), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Shoddy_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Shoddy_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-static PyModuleDef shoddymodule = {
- PyModuleDef_HEAD_INIT,
- "shoddy",
- "Shoddy module",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_shoddy(void)
-{
- PyObject *m;
-
- ShoddyType.tp_base = &PyList_Type;
- if (PyType_Ready(&ShoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&shoddymodule);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&ShoddyType);
- PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
- return m;
-}
diff --git a/Doc/includes/sqlite3/adapter_datetime.py b/Doc/includes/sqlite3/adapter_datetime.py
index be33395100c325..d5221d80c35c8a 100644
--- a/Doc/includes/sqlite3/adapter_datetime.py
+++ b/Doc/includes/sqlite3/adapter_datetime.py
@@ -13,3 +13,5 @@ def adapt_datetime(ts):
now = datetime.datetime.now()
cur.execute("select ?", (now,))
print(cur.fetchone()[0])
+
+con.close()
diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py
index 6b1af8415648a4..77daf8f16d227b 100644
--- a/Doc/includes/sqlite3/adapter_point_1.py
+++ b/Doc/includes/sqlite3/adapter_point_1.py
@@ -14,3 +14,5 @@ def __conform__(self, protocol):
p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print(cur.fetchone()[0])
+
+con.close()
diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py
index d670700f0491b1..cb86331692b61d 100644
--- a/Doc/includes/sqlite3/adapter_point_2.py
+++ b/Doc/includes/sqlite3/adapter_point_2.py
@@ -15,3 +15,5 @@ def adapt_point(point):
p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print(cur.fetchone()[0])
+
+con.close()
diff --git a/Doc/includes/sqlite3/connect_db_1.py b/Doc/includes/sqlite3/connect_db_1.py
deleted file mode 100644
index 1b975232865aef..00000000000000
--- a/Doc/includes/sqlite3/connect_db_1.py
+++ /dev/null
@@ -1,3 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect("mydb")
diff --git a/Doc/includes/sqlite3/connect_db_2.py b/Doc/includes/sqlite3/connect_db_2.py
deleted file mode 100644
index f9728b36135ed7..00000000000000
--- a/Doc/includes/sqlite3/connect_db_2.py
+++ /dev/null
@@ -1,3 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect(":memory:")
diff --git a/Doc/includes/sqlite3/countcursors.py b/Doc/includes/sqlite3/countcursors.py
index ef3e70a2a9cfc5..112f47703a2ff4 100644
--- a/Doc/includes/sqlite3/countcursors.py
+++ b/Doc/includes/sqlite3/countcursors.py
@@ -13,3 +13,5 @@ def cursor(self, *args, **kwargs):
cur1 = con.cursor()
cur2 = con.cursor()
print(con.numcursors)
+
+con.close()
diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py
index 7af4ad1ecfbcca..6db77d45046e1f 100644
--- a/Doc/includes/sqlite3/ctx_manager.py
+++ b/Doc/includes/sqlite3/ctx_manager.py
@@ -14,3 +14,7 @@
con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
print("couldn't add Joe twice")
+
+# Connection object used as context manager only commits or rollbacks transactions,
+# so the connection object should be closed manually
+con.close()
diff --git a/Doc/includes/sqlite3/execsql_fetchonerow.py b/Doc/includes/sqlite3/execsql_fetchonerow.py
index 078873bfc979a9..115bcb50c7c754 100644
--- a/Doc/includes/sqlite3/execsql_fetchonerow.py
+++ b/Doc/includes/sqlite3/execsql_fetchonerow.py
@@ -15,3 +15,5 @@
cur.execute(SELECT)
for row in cur:
print('%s is %d years old.' % (row[0], row[1]))
+
+con.close()
diff --git a/Doc/includes/sqlite3/execsql_printall_1.py b/Doc/includes/sqlite3/execsql_printall_1.py
index a4ce5c528149c5..19306e6e3ca7d1 100644
--- a/Doc/includes/sqlite3/execsql_printall_1.py
+++ b/Doc/includes/sqlite3/execsql_printall_1.py
@@ -11,3 +11,5 @@
# Retrieve all rows as a sequence and print that sequence:
print(cur.fetchall())
+
+con.close()
diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py
index f864a8984e4e90..3466b1265a5bf2 100644
--- a/Doc/includes/sqlite3/execute_1.py
+++ b/Doc/includes/sqlite3/execute_1.py
@@ -14,3 +14,5 @@
cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age})
print(cur.fetchone())
+
+con.close()
diff --git a/Doc/includes/sqlite3/execute_3.py b/Doc/includes/sqlite3/execute_3.py
deleted file mode 100644
index 0353683fc70476..00000000000000
--- a/Doc/includes/sqlite3/execute_3.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import sqlite3
-
-con = sqlite3.connect("mydb")
-
-cur = con.cursor()
-
-who = "Yeltsin"
-age = 72
-
-cur.execute("select name_last, age from people where name_last=:who and age=:age",
- locals())
-print(cur.fetchone())
diff --git a/Doc/includes/sqlite3/executemany_1.py b/Doc/includes/sqlite3/executemany_1.py
index efae10637c7e8f..edf6f8b7ebe61a 100644
--- a/Doc/includes/sqlite3/executemany_1.py
+++ b/Doc/includes/sqlite3/executemany_1.py
@@ -22,3 +22,5 @@ def __next__(self):
cur.execute("select c from characters")
print(cur.fetchall())
+
+con.close()
diff --git a/Doc/includes/sqlite3/executemany_2.py b/Doc/includes/sqlite3/executemany_2.py
index 527358ebc28e1f..02a594c861e15b 100644
--- a/Doc/includes/sqlite3/executemany_2.py
+++ b/Doc/includes/sqlite3/executemany_2.py
@@ -13,3 +13,5 @@ def char_generator():
cur.execute("select c from characters")
print(cur.fetchall())
+
+con.close()
diff --git a/Doc/includes/sqlite3/executescript.py b/Doc/includes/sqlite3/executescript.py
index 7e5358178d4c0a..aea8943fbee598 100644
--- a/Doc/includes/sqlite3/executescript.py
+++ b/Doc/includes/sqlite3/executescript.py
@@ -22,3 +22,4 @@
1987
);
""")
+con.close()
diff --git a/Doc/includes/sqlite3/insert_more_people.py b/Doc/includes/sqlite3/insert_more_people.py
index edbc79e7e5b6cc..10cf937243f6da 100644
--- a/Doc/includes/sqlite3/insert_more_people.py
+++ b/Doc/includes/sqlite3/insert_more_people.py
@@ -14,3 +14,5 @@
# The changes will not be saved unless the transaction is committed explicitly:
con.commit()
+
+con.close()
diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py
index b997c70668ace4..624cfe262f38b3 100644
--- a/Doc/includes/sqlite3/load_extension.py
+++ b/Doc/includes/sqlite3/load_extension.py
@@ -24,3 +24,5 @@
""")
for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
print(row)
+
+con.close()
diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py
index 0056b2d6ce84ef..16dc348bf001e2 100644
--- a/Doc/includes/sqlite3/md5func.py
+++ b/Doc/includes/sqlite3/md5func.py
@@ -9,3 +9,5 @@ def md5sum(t):
cur = con.cursor()
cur.execute("select md5(?)", (b"foo",))
print(cur.fetchone()[0])
+
+con.close()
diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py
index d2dfd2c0b98d3b..11f96395b6c485 100644
--- a/Doc/includes/sqlite3/mysumaggr.py
+++ b/Doc/includes/sqlite3/mysumaggr.py
@@ -18,3 +18,5 @@ def finalize(self):
cur.execute("insert into test(i) values (2)")
cur.execute("select mysum(i) from test")
print(cur.fetchone()[0])
+
+con.close()
diff --git a/Doc/includes/sqlite3/parse_colnames.py b/Doc/includes/sqlite3/parse_colnames.py
index cc68c76459ecea..5f01dbfe1cb524 100644
--- a/Doc/includes/sqlite3/parse_colnames.py
+++ b/Doc/includes/sqlite3/parse_colnames.py
@@ -6,3 +6,5 @@
cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),))
dt = cur.fetchone()[0]
print(dt, type(dt))
+
+con.close()
diff --git a/Doc/includes/sqlite3/pysqlite_datetime.py b/Doc/includes/sqlite3/pysqlite_datetime.py
index 68d49358a578b3..5d843f906b3062 100644
--- a/Doc/includes/sqlite3/pysqlite_datetime.py
+++ b/Doc/includes/sqlite3/pysqlite_datetime.py
@@ -18,3 +18,5 @@
row = cur.fetchone()
print("current_date", row[0], type(row[0]))
print("current_timestamp", row[1], type(row[1]))
+
+con.close()
diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py
index e436ffc6c80225..9de6e7b1b9052a 100644
--- a/Doc/includes/sqlite3/row_factory.py
+++ b/Doc/includes/sqlite3/row_factory.py
@@ -11,3 +11,5 @@ def dict_factory(cursor, row):
cur = con.cursor()
cur.execute("select 1 as a")
print(cur.fetchone()["a"])
+
+con.close()
diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py
index 92b5ad60cb5791..fc60287069a854 100644
--- a/Doc/includes/sqlite3/rowclass.py
+++ b/Doc/includes/sqlite3/rowclass.py
@@ -10,3 +10,5 @@
assert row["name"] == row["nAmE"]
assert row[1] == row["age"]
assert row[1] == row["AgE"]
+
+con.close()
diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py
index 71600d4f60c55e..98a39411495cba 100644
--- a/Doc/includes/sqlite3/shortcut_methods.py
+++ b/Doc/includes/sqlite3/shortcut_methods.py
@@ -18,3 +18,7 @@
print(row)
print("I just deleted", con.execute("delete from person").rowcount, "rows")
+
+# close is not a shortcut method and it's not called automatically,
+# so the connection object should be closed manually
+con.close()
diff --git a/Doc/includes/sqlite3/simple_tableprinter.py b/Doc/includes/sqlite3/simple_tableprinter.py
index 231d8726cd436e..148a1707f948bc 100644
--- a/Doc/includes/sqlite3/simple_tableprinter.py
+++ b/Doc/includes/sqlite3/simple_tableprinter.py
@@ -24,3 +24,5 @@
print(fieldValue.ljust(FIELD_MAX_WIDTH), end=' ')
print() # Finish the row with a newline.
+
+con.close()
diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py
index 5f96cdb58da1ab..a857a155cdd4ff 100644
--- a/Doc/includes/sqlite3/text_factory.py
+++ b/Doc/includes/sqlite3/text_factory.py
@@ -25,3 +25,5 @@
cur.execute("select ?", ("bar",))
row = cur.fetchone()
assert row[0] == "barfoo"
+
+con.close()
diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c
new file mode 100644
index 00000000000000..b2c26e73ebaf7e
--- /dev/null
+++ b/Doc/includes/sublist.c
@@ -0,0 +1,69 @@
+#define PY_SSIZE_T_CLEAN
+#include
+
+typedef struct {
+ PyListObject list;
+ int state;
+} SubListObject;
+
+static PyObject *
+SubList_increment(SubListObject *self, PyObject *unused)
+{
+ self->state++;
+ return PyLong_FromLong(self->state);
+}
+
+static PyMethodDef SubList_methods[] = {
+ {"increment", (PyCFunction) SubList_increment, METH_NOARGS,
+ PyDoc_STR("increment state counter")},
+ {NULL},
+};
+
+static int
+SubList_init(SubListObject *self, PyObject *args, PyObject *kwds)
+{
+ if (PyList_Type.tp_init((PyObject *) self, args, kwds) < 0)
+ return -1;
+ self->state = 0;
+ return 0;
+}
+
+static PyTypeObject SubListType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "sublist.SubList",
+ .tp_doc = "SubList objects",
+ .tp_basicsize = sizeof(SubListObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_init = (initproc) SubList_init,
+ .tp_methods = SubList_methods,
+};
+
+static PyModuleDef sublistmodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "sublist",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_sublist(void)
+{
+ PyObject *m;
+ SubListType.tp_base = &PyList_Type;
+ if (PyType_Ready(&SubListType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&sublistmodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&SubListType);
+ if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
+ Py_DECREF(&SubListType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
+ return m;
+}
diff --git a/Doc/includes/test.py b/Doc/includes/test.py
index 9e9d4a67121cae..09ebe3fec0bdbe 100644
--- a/Doc/includes/test.py
+++ b/Doc/includes/test.py
@@ -1,181 +1,168 @@
-"""Test module for the noddy examples
+"""Test module for the custom examples
-Noddy 1:
+Custom 1:
->>> import noddy
->>> n1 = noddy.Noddy()
->>> n2 = noddy.Noddy()
->>> del n1
->>> del n2
+>>> import custom
+>>> c1 = custom.Custom()
+>>> c2 = custom.Custom()
+>>> del c1
+>>> del c2
-Noddy 2
+Custom 2
->>> import noddy2
->>> n1 = noddy2.Noddy('jim', 'fulton', 42)
->>> n1.first
+>>> import custom2
+>>> c1 = custom2.Custom('jim', 'fulton', 42)
+>>> c1.first
'jim'
->>> n1.last
+>>> c1.last
'fulton'
->>> n1.number
+>>> c1.number
42
->>> n1.name()
+>>> c1.name()
'jim fulton'
->>> n1.first = 'will'
->>> n1.name()
+>>> c1.first = 'will'
+>>> c1.name()
'will fulton'
->>> n1.last = 'tell'
->>> n1.name()
+>>> c1.last = 'tell'
+>>> c1.name()
'will tell'
->>> del n1.first
->>> n1.name()
+>>> del c1.first
+>>> c1.name()
Traceback (most recent call last):
...
AttributeError: first
->>> n1.first
+>>> c1.first
Traceback (most recent call last):
...
AttributeError: first
->>> n1.first = 'drew'
->>> n1.first
+>>> c1.first = 'drew'
+>>> c1.first
'drew'
->>> del n1.number
+>>> del c1.number
Traceback (most recent call last):
...
TypeError: can't delete numeric/char attribute
->>> n1.number=2
->>> n1.number
+>>> c1.number=2
+>>> c1.number
2
->>> n1.first = 42
->>> n1.name()
+>>> c1.first = 42
+>>> c1.name()
'42 tell'
->>> n2 = noddy2.Noddy()
->>> n2.name()
+>>> c2 = custom2.Custom()
+>>> c2.name()
' '
->>> n2.first
+>>> c2.first
''
->>> n2.last
+>>> c2.last
''
->>> del n2.first
->>> n2.first
+>>> del c2.first
+>>> c2.first
Traceback (most recent call last):
...
AttributeError: first
->>> n2.first
+>>> c2.first
Traceback (most recent call last):
...
AttributeError: first
->>> n2.name()
+>>> c2.name()
Traceback (most recent call last):
File "", line 1, in ?
AttributeError: first
->>> n2.number
+>>> c2.number
0
->>> n3 = noddy2.Noddy('jim', 'fulton', 'waaa')
+>>> n3 = custom2.Custom('jim', 'fulton', 'waaa')
Traceback (most recent call last):
File "", line 1, in ?
-TypeError: an integer is required
->>> del n1
->>> del n2
+TypeError: an integer is required (got type str)
+>>> del c1
+>>> del c2
-Noddy 3
+Custom 3
->>> import noddy3
->>> n1 = noddy3.Noddy('jim', 'fulton', 42)
->>> n1 = noddy3.Noddy('jim', 'fulton', 42)
->>> n1.name()
+>>> import custom3
+>>> c1 = custom3.Custom('jim', 'fulton', 42)
+>>> c1 = custom3.Custom('jim', 'fulton', 42)
+>>> c1.name()
'jim fulton'
->>> del n1.first
+>>> del c1.first
Traceback (most recent call last):
File "", line 1, in ?
TypeError: Cannot delete the first attribute
->>> n1.first = 42
+>>> c1.first = 42
Traceback (most recent call last):
File "", line 1, in ?
TypeError: The first attribute value must be a string
->>> n1.first = 'will'
->>> n1.name()
+>>> c1.first = 'will'
+>>> c1.name()
'will fulton'
->>> n2 = noddy3.Noddy()
->>> n2 = noddy3.Noddy()
->>> n2 = noddy3.Noddy()
->>> n3 = noddy3.Noddy('jim', 'fulton', 'waaa')
+>>> c2 = custom3.Custom()
+>>> c2 = custom3.Custom()
+>>> c2 = custom3.Custom()
+>>> n3 = custom3.Custom('jim', 'fulton', 'waaa')
Traceback (most recent call last):
File "", line 1, in ?
-TypeError: an integer is required
->>> del n1
->>> del n2
+TypeError: an integer is required (got type str)
+>>> del c1
+>>> del c2
-Noddy 4
+Custom 4
->>> import noddy4
->>> n1 = noddy4.Noddy('jim', 'fulton', 42)
->>> n1.first
+>>> import custom4
+>>> c1 = custom4.Custom('jim', 'fulton', 42)
+>>> c1.first
'jim'
->>> n1.last
+>>> c1.last
'fulton'
->>> n1.number
+>>> c1.number
42
->>> n1.name()
+>>> c1.name()
'jim fulton'
->>> n1.first = 'will'
->>> n1.name()
+>>> c1.first = 'will'
+>>> c1.name()
'will fulton'
->>> n1.last = 'tell'
->>> n1.name()
+>>> c1.last = 'tell'
+>>> c1.name()
'will tell'
->>> del n1.first
->>> n1.name()
+>>> del c1.first
Traceback (most recent call last):
...
-AttributeError: first
->>> n1.first
-Traceback (most recent call last):
-...
-AttributeError: first
->>> n1.first = 'drew'
->>> n1.first
+TypeError: Cannot delete the first attribute
+>>> c1.name()
+'will tell'
+>>> c1.first = 'drew'
+>>> c1.first
'drew'
->>> del n1.number
+>>> del c1.number
Traceback (most recent call last):
...
TypeError: can't delete numeric/char attribute
->>> n1.number=2
->>> n1.number
+>>> c1.number=2
+>>> c1.number
2
->>> n1.first = 42
->>> n1.name()
-'42 tell'
->>> n2 = noddy4.Noddy()
->>> n2 = noddy4.Noddy()
->>> n2 = noddy4.Noddy()
->>> n2 = noddy4.Noddy()
->>> n2.name()
+>>> c1.first = 42
+Traceback (most recent call last):
+...
+TypeError: The first attribute value must be a string
+>>> c1.name()
+'drew tell'
+>>> c2 = custom4.Custom()
+>>> c2 = custom4.Custom()
+>>> c2 = custom4.Custom()
+>>> c2 = custom4.Custom()
+>>> c2.name()
' '
->>> n2.first
+>>> c2.first
''
->>> n2.last
+>>> c2.last
''
->>> del n2.first
->>> n2.first
-Traceback (most recent call last):
-...
-AttributeError: first
->>> n2.first
-Traceback (most recent call last):
-...
-AttributeError: first
->>> n2.name()
-Traceback (most recent call last):
- File "", line 1, in ?
-AttributeError: first
->>> n2.number
+>>> c2.number
0
->>> n3 = noddy4.Noddy('jim', 'fulton', 'waaa')
+>>> n3 = custom4.Custom('jim', 'fulton', 'waaa')
Traceback (most recent call last):
- File "", line 1, in ?
-TypeError: an integer is required
+...
+TypeError: an integer is required (got type str)
Test cyclic gc(?)
@@ -183,15 +170,14 @@
>>> import gc
>>> gc.disable()
->>> x = []
->>> l = [x]
->>> n2.first = l
->>> n2.first
-[[]]
->>> l.append(n2)
->>> del l
->>> del n1
->>> del n2
+>>> class Subclass(custom4.Custom): pass
+...
+>>> s = Subclass()
+>>> s.cycle = [s]
+>>> s.cycle.append(s.cycle)
+>>> x = object()
+>>> s.x = x
+>>> del s
>>> sys.getrefcount(x)
3
>>> ignore = gc.collect()
diff --git a/Doc/includes/tzinfo_examples.py b/Doc/includes/tzinfo_examples.py
index ae5a5092665f09..9b9e32a553e7d8 100644
--- a/Doc/includes/tzinfo_examples.py
+++ b/Doc/includes/tzinfo_examples.py
@@ -1,4 +1,4 @@
-from datetime import tzinfo, timedelta, datetime, timezone
+from datetime import tzinfo, timedelta, datetime
ZERO = timedelta(0)
HOUR = timedelta(hours=1)
diff --git a/Doc/install/index.rst b/Doc/install/index.rst
index 0545b8f33d0378..b82c1b23f11f0d 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -283,7 +283,9 @@ Windows, choose :menuselection:`Start --> Programs --> Python X.Y -->
Python (command line)`. Once the interpreter is started, you type Python code
at the prompt. For example, on my Linux system, I type the three Python
statements shown below, and get the output as shown, to find out my
-:file:`{prefix}` and :file:`{exec-prefix}`::
+:file:`{prefix}` and :file:`{exec-prefix}`:
+
+.. code-block:: pycon
Python 2.4 (#26, Aug 7 2004, 17:19:02)
Type "help", "copyright", "credits" or "license" for more information.
@@ -552,10 +554,10 @@ C headers ``--install-headers``
These override options can be relative, absolute,
or explicitly defined in terms of one of the installation base directories.
-(There are two installation base directories, and they are normally the same---
-they only differ when you use the Unix "prefix scheme" and supply different
-``--prefix`` and ``--exec-prefix`` options; using ``--install-lib`` will
-override values computed or given for ``--install-purelib`` and
+(There are two installation base directories, and they are normally the
+same---they only differ when you use the Unix "prefix scheme" and supply
+different ``--prefix`` and ``--exec-prefix`` options; using ``--install-lib``
+will override values computed or given for ``--install-purelib`` and
``--install-platlib``, and is recommended for schemes that don't make a
difference between Python and extension modules.)
@@ -576,16 +578,16 @@ scripts will wind up in :file:`/usr/local/python/bin`. If you want them in
python setup.py install --install-scripts=/usr/local/bin
-(This performs an installation using the "prefix scheme," where the prefix is
+(This performs an installation using the "prefix scheme", where the prefix is
whatever your Python interpreter was installed with--- :file:`/usr/local/python`
in this case.)
If you maintain Python on Windows, you might want third-party modules to live in
a subdirectory of :file:`{prefix}`, rather than right in :file:`{prefix}`
-itself. This is almost as easy as customizing the script installation directory
----you just have to remember that there are two types of modules to worry about,
-Python and extension modules, which can conveniently be both controlled by one
-option::
+itself. This is almost as easy as customizing the script installation
+directory---you just have to remember that there are two types of modules
+to worry about, Python and extension modules, which can conveniently be both
+controlled by one option::
python setup.py install --install-lib=Site
@@ -622,7 +624,9 @@ parsing your configuration file(s).
Obviously, specifying the entire installation scheme every time you install a
new module distribution would be very tedious. Thus, you can put these options
-into your Distutils config file (see section :ref:`inst-config-files`)::
+into your Distutils config file (see section :ref:`inst-config-files`):
+
+.. code-block:: ini
[install]
install-base=$HOME
@@ -631,7 +635,9 @@ into your Distutils config file (see section :ref:`inst-config-files`)::
install-scripts=python/scripts
install-data=python/data
-or, equivalently, ::
+or, equivalently,
+
+.. code-block:: ini
[install]
install-base=$HOME/python
@@ -718,7 +724,9 @@ A slightly less convenient way is to edit the :file:`site.py` file in Python's
standard library, and modify ``sys.path``. :file:`site.py` is automatically
imported when the Python interpreter is executed, unless the :option:`-S` switch
is supplied to suppress this behaviour. So you could simply edit
-:file:`site.py` and add two lines to it::
+:file:`site.py` and add two lines to it:
+
+.. code-block:: python
import sys
sys.path.append('/www/python/')
@@ -839,7 +847,9 @@ plus a ``global`` section for global options that affect every command. Each
section consists of one option per line, specified as ``option=value``.
For example, the following is a complete config file that just forces all
-commands to run quietly by default::
+commands to run quietly by default:
+
+.. code-block:: ini
[global]
verbose=0
@@ -853,7 +863,9 @@ distribution.
You could override the default "build base" directory and make the
:command:`build\*` commands always forcibly rebuild all files with the
-following::
+following:
+
+.. code-block:: ini
[build]
build-base=blib
diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst
index f9a224be92b8be..c1a9a1f0a58d76 100644
--- a/Doc/installing/index.rst
+++ b/Doc/installing/index.rst
@@ -44,16 +44,16 @@ Key terms
``venv``. It allows virtual environments to be used on versions of
Python prior to 3.4, which either don't provide ``venv`` at all, or
aren't able to automatically install ``pip`` into created environments.
-* The `Python Packaging Index `__ is a public
+* The `Python Packaging Index `__ is a public
repository of open source licensed packages made available for use by
other Python users.
* the `Python Packaging Authority
- `__ are the group of
+ `__ is the group of
developers and documentation authors responsible for the maintenance and
evolution of the standard packaging tools and the associated metadata and
file format standards. They maintain a variety of tools, documentation,
and issue trackers on both `GitHub `__ and
- `BitBucket `__.
+ `Bitbucket `__.
* ``distutils`` is the original build and distribution system first added to
the Python standard library in 1998. While direct use of ``distutils`` is
being phased out, it still laid the foundation for the current packaging
diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst
index deb5e10f6ef7e9..c3ff3e607e7978 100644
--- a/Doc/library/2to3.rst
+++ b/Doc/library/2to3.rst
@@ -385,7 +385,7 @@ and off individually. They are described here in more detail.
.. 2to3fixer:: reload
- Converts :func:`reload` to :func:`imp.reload`.
+ Converts :func:`reload` to :func:`importlib.reload`.
.. 2to3fixer:: renames
@@ -456,7 +456,7 @@ and off individually. They are described here in more detail.
-------------------------------
.. module:: lib2to3
- :synopsis: the 2to3 library
+ :synopsis: The 2to3 library
.. moduleauthor:: Guido van Rossum
.. moduleauthor:: Collin Winter
diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst
index 67cb70944f4da1..d1c28f479e94c9 100644
--- a/Doc/library/_thread.rst
+++ b/Doc/library/_thread.rst
@@ -53,8 +53,12 @@ This module defines the following constants and functions:
.. function:: interrupt_main()
- Raise a :exc:`KeyboardInterrupt` exception in the main thread. A subthread can
- use this function to interrupt the main thread.
+ Simulate the effect of a :data:`signal.SIGINT` signal arriving in the main
+ thread. A thread can use this function to interrupt the main thread.
+
+ If :data:`signal.SIGINT` isn't handled by Python (it was set to
+ :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does
+ nothing.
.. function:: exit()
@@ -101,7 +105,8 @@ This module defines the following constants and functions:
memory page size - platform documentation should be referred to for more
information (4 KiB pages are common; using multiples of 4096 for the stack size is
the suggested approach in the absence of more specific information).
- Availability: Windows, systems with POSIX threads.
+
+ .. availability:: Windows, systems with POSIX threads.
.. data:: TIMEOUT_MAX
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index 9522dd62049138..fc39a2e7582b3a 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -18,10 +18,10 @@ see the PEP for why this was added to Python. (See also :pep:`3141` and the
:mod:`numbers` module regarding a type hierarchy for numbers based on ABCs.)
The :mod:`collections` module has some concrete classes that derive from
-ABCs; these can, of course, be further derived. In addition the
+ABCs; these can, of course, be further derived. In addition, the
:mod:`collections.abc` submodule has some ABCs that can be used to test whether
-a class or instance provides a particular interface, for example, is it
-hashable or a mapping.
+a class or instance provides a particular interface, for example, if it is
+hashable or if it is a mapping.
This module provides the metaclass :class:`ABCMeta` for defining ABCs and
@@ -160,7 +160,7 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance:
-The :mod:`abc` module also provides the following decorators:
+The :mod:`abc` module also provides the following decorator:
.. decorator:: abstractmethod
@@ -217,7 +217,7 @@ The :mod:`abc` module also provides the following decorators:
the descriptor must identify itself as abstract using
:attr:`__isabstractmethod__`. In general, this attribute should be ``True``
if any of the methods used to compose the descriptor are abstract. For
- example, Python's built-in property does the equivalent of::
+ example, Python's built-in :class:`property` does the equivalent of::
class Descriptor:
...
@@ -236,8 +236,15 @@ The :mod:`abc` module also provides the following decorators:
multiple-inheritance.
+The :mod:`abc` module also supports the following legacy decorators:
+
.. decorator:: abstractclassmethod
+ .. versionadded:: 3.2
+ .. deprecated:: 3.3
+ It is now possible to use :class:`classmethod` with
+ :func:`abstractmethod`, making this decorator redundant.
+
A subclass of the built-in :func:`classmethod`, indicating an abstract
classmethod. Otherwise it is similar to :func:`abstractmethod`.
@@ -251,14 +258,14 @@ The :mod:`abc` module also provides the following decorators:
def my_abstract_classmethod(cls, ...):
...
+
+.. decorator:: abstractstaticmethod
+
.. versionadded:: 3.2
.. deprecated:: 3.3
- It is now possible to use :class:`classmethod` with
+ It is now possible to use :class:`staticmethod` with
:func:`abstractmethod`, making this decorator redundant.
-
-.. decorator:: abstractstaticmethod
-
A subclass of the built-in :func:`staticmethod`, indicating an abstract
staticmethod. Otherwise it is similar to :func:`abstractmethod`.
@@ -272,23 +279,17 @@ The :mod:`abc` module also provides the following decorators:
def my_abstract_staticmethod(...):
...
- .. versionadded:: 3.2
- .. deprecated:: 3.3
- It is now possible to use :class:`staticmethod` with
- :func:`abstractmethod`, making this decorator redundant.
-
.. decorator:: abstractproperty
+ .. deprecated:: 3.3
+ It is now possible to use :class:`property`, :meth:`property.getter`,
+ :meth:`property.setter` and :meth:`property.deleter` with
+ :func:`abstractmethod`, making this decorator redundant.
+
A subclass of the built-in :func:`property`, indicating an abstract
property.
- Using this function requires that the class's metaclass is :class:`ABCMeta`
- or is derived from it. A class that has a metaclass derived from
- :class:`ABCMeta` cannot be instantiated unless all of its abstract methods
- and properties are overridden. The abstract properties can be called using
- any of the normal 'super' call mechanisms.
-
This special case is deprecated, as the :func:`property` decorator
is now correctly identified as abstract when applied to an abstract
method::
@@ -322,12 +323,6 @@ The :mod:`abc` module also provides the following decorators:
...
- .. deprecated:: 3.3
- It is now possible to use :class:`property`, :meth:`property.getter`,
- :meth:`property.setter` and :meth:`property.deleter` with
- :func:`abstractmethod`, making this decorator redundant.
-
-
The :mod:`abc` module also provides the following functions:
.. function:: get_cache_token()
diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst
index 970a7aeb98a713..7328907730fb10 100644
--- a/Doc/library/aifc.rst
+++ b/Doc/library/aifc.rst
@@ -45,7 +45,7 @@ Module :mod:`aifc` defines the following function:
time how many samples you are going to write in total and use
:meth:`writeframesraw` and :meth:`setnframes`.
The :func:`.open` function may be used in a :keyword:`with` statement. When
- the :keyword:`with` block completes, the :meth:`~aifc.close` method is called.
+ the :keyword:`!with` block completes, the :meth:`~aifc.close` method is called.
.. versionchanged:: 3.4
Support for the :keyword:`with` statement was added.
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index 53e670161dd5b3..4a24c267ec79f4 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -712,7 +712,7 @@ be positional::
Namespace(bar='BAR', foo='FOO')
>>> parser.parse_args(['--foo', 'FOO'])
usage: PROG [-h] [-f FOO] bar
- PROG: error: too few arguments
+ PROG: error: the following arguments are required: bar
action
@@ -778,10 +778,12 @@ how the command-line arguments should be handled. The supplied actions are:
example, this is useful for increasing verbosity levels::
>>> parser = argparse.ArgumentParser()
- >>> parser.add_argument('--verbose', '-v', action='count')
+ >>> parser.add_argument('--verbose', '-v', action='count', default=0)
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)
+ Note, the *default* will be ``None`` unless explicitly set to *0*.
+
* ``'help'`` - This prints a complete help message for all the options in the
current parser and then exits. By default a help action is automatically
added to the parser. See :class:`ArgumentParser` for details of how the
@@ -844,6 +846,8 @@ values are:
Note that ``nargs=1`` produces a list of one item. This is different from
the default, in which the item is produced by itself.
+.. index:: single: ? (question mark); in argparse module
+
* ``'?'``. One argument will be consumed from the command line if possible, and
produced as a single item. If no command-line argument is present, the value from
default_ will be produced. Note that for optional arguments, there is an
@@ -876,6 +880,8 @@ values are:
Namespace(infile=<_io.TextIOWrapper name='' encoding='UTF-8'>,
outfile=<_io.TextIOWrapper name='' encoding='UTF-8'>)
+.. index:: single: * (asterisk); in argparse module
+
* ``'*'``. All command-line arguments present are gathered into a list. Note that
it generally doesn't make much sense to have more than one positional argument
with ``nargs='*'``, but multiple optional arguments with ``nargs='*'`` is
@@ -888,6 +894,8 @@ values are:
>>> parser.parse_args('a b --foo x y --bar 1 2'.split())
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
+.. index:: single: + (plus); in argparse module
+
* ``'+'``. Just like ``'*'``, all command-line args present are gathered into a
list. Additionally, an error message will be generated if there wasn't at
least one command-line argument present. For example::
@@ -898,7 +906,7 @@ values are:
Namespace(foo=['a', 'b'])
>>> parser.parse_args([])
usage: PROG [-h] foo [foo ...]
- PROG: error: too few arguments
+ PROG: error: the following arguments are required: foo
.. _`argparse.REMAINDER`:
@@ -981,7 +989,7 @@ is used when no command-line argument was present::
Providing ``default=argparse.SUPPRESS`` causes no attribute to be added if the
-command-line argument was not present.::
+command-line argument was not present::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
@@ -1539,7 +1547,7 @@ Sub-commands
.. method:: ArgumentParser.add_subparsers([title], [description], [prog], \
[parser_class], [action], \
- [option_string], [dest], [required] \
+ [option_string], [dest], [required], \
[help], [metavar])
Many programs split up their functionality into a number of sub-commands,
@@ -1577,7 +1585,7 @@ Sub-commands
stored; by default ``None`` and no value is stored
* required_ - Whether or not a subcommand must be provided, by default
- ``True``.
+ ``False`` (added in 3.7)
* help_ - help for sub-parser group in help output, by default ``None``
@@ -1733,6 +1741,9 @@ Sub-commands
>>> parser.parse_args(['2', 'frobble'])
Namespace(subparser_name='2', y='frobble')
+ .. versionchanged:: 3.7
+ New *required* keyword argument.
+
FileType objects
^^^^^^^^^^^^^^^^
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index 4ac7bb5391a7a4..901a1356758a35 100644
--- a/Doc/library/array.rst
+++ b/Doc/library/array.rst
@@ -36,9 +36,9 @@ defined:
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'L'`` | unsigned long | int | 4 | |
+-----------+--------------------+-------------------+-----------------------+-------+
-| ``'q'`` | signed long long | int | 8 | \(2) |
+| ``'q'`` | signed long long | int | 8 | |
+-----------+--------------------+-------------------+-----------------------+-------+
-| ``'Q'`` | unsigned long long | int | 8 | \(2) |
+| ``'Q'`` | unsigned long long | int | 8 | |
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'f'`` | float | float | 4 | |
+-----------+--------------------+-------------------+-----------------------+-------+
@@ -57,13 +57,6 @@ Notes:
.. deprecated-removed:: 3.3 4.0
-(2)
- The ``'q'`` and ``'Q'`` type codes are available only if
- the platform C compiler used to build Python supports C :c:type:`long long`,
- or, on Windows, :c:type:`__int64`.
-
- .. versionadded:: 3.3
-
The actual representation of values is determined by the machine architecture
(strictly speaking, by the C implementation). The actual size can be accessed
through the :attr:`itemsize` attribute.
@@ -179,6 +172,8 @@ The following data items and methods are also supported:
Deprecated alias for :meth:`frombytes`.
+ .. deprecated-removed:: 3.2 3.9
+
.. method:: array.fromunicode(s)
@@ -241,6 +236,8 @@ The following data items and methods are also supported:
Deprecated alias for :meth:`tobytes`.
+ .. deprecated-removed:: 3.2 3.9
+
.. method:: array.tounicode()
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index b7f610ba8b2a5f..1dddad8275ac9f 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -41,6 +41,9 @@ Node classes
with alternatives (aka "sums"), the left-hand side class is abstract: only
instances of specific constructor nodes are ever created.
+ .. index:: single: ? (question mark); in AST grammar
+ .. index:: single: * (asterisk); in AST grammar
+
.. attribute:: _fields
Each concrete class has an attribute :attr:`_fields` which gives the names
@@ -113,6 +116,11 @@ and classes for traversing abstract syntax trees:
Parse the source into an AST node. Equivalent to ``compile(source,
filename, mode, ast.PyCF_ONLY_AST)``.
+ .. warning::
+ It is possible to crash the Python interpreter with a
+ sufficiently large/complex string due to stack depth limitations
+ in Python's AST compiler.
+
.. function:: literal_eval(node_or_string)
@@ -126,6 +134,11 @@ and classes for traversing abstract syntax trees:
capable of evaluating arbitrarily complex expressions, for example involving
operators or indexing.
+ .. warning::
+ It is possible to crash the Python interpreter with a
+ sufficiently large/complex string due to stack depth limitations
+ in Python's AST compiler.
+
.. versionchanged:: 3.2
Now allows bytes and set literals.
@@ -141,10 +154,6 @@ and classes for traversing abstract syntax trees:
.. versionchanged:: 3.5
:class:`AsyncFunctionDef` is now supported.
- .. versionchanged:: 3.7
- The docstring is now exported from the node docstring field, instead of
- the first body statement.
-
.. function:: fix_missing_locations(node)
@@ -231,11 +240,11 @@ and classes for traversing abstract syntax trees:
class RewriteName(NodeTransformer):
def visit_Name(self, node):
- return copy_location(Subscript(
+ return Subscript(
value=Name(id='data', ctx=Load()),
slice=Index(value=Str(s=node.id)),
ctx=node.ctx
- ), node)
+ )
Keep in mind that if the node you're operating on has child nodes you must
either transform the child nodes yourself or call the :meth:`generic_visit`
@@ -245,6 +254,14 @@ and classes for traversing abstract syntax trees:
statement nodes), the visitor may also return a list of nodes rather than
just a single node.
+ If :class:`NodeTransformer` introduces new nodes (that weren't part of
+ original tree) without giving them location information (such as
+ :attr:`lineno`), :func:`fix_missing_locations` should be called with
+ the new sub-tree to recalculate the location information::
+
+ tree = ast.parse('foo', mode='eval')
+ new_tree = fix_missing_locations(RewriteName().visit(tree))
+
Usually you use the transformer like this::
node = YourTransformer().visit(node)
@@ -253,11 +270,12 @@ and classes for traversing abstract syntax trees:
.. function:: dump(node, annotate_fields=True, include_attributes=False)
Return a formatted dump of the tree in *node*. This is mainly useful for
- debugging purposes. The returned string will show the names and the values
- for fields. This makes the code impossible to evaluate, so if evaluation is
- wanted *annotate_fields* must be set to ``False``. Attributes such as line
+ debugging purposes. If *annotate_fields* is true (by default),
+ the returned string will show the names and the values for fields.
+ If *annotate_fields* is false, the result string will be more compact by
+ omitting unambiguous field names. Attributes such as line
numbers and column offsets are not dumped by default. If this is wanted,
- *include_attributes* can be set to ``True``.
+ *include_attributes* can be set to true.
.. seealso::
diff --git a/Doc/library/asyncio-api-index.rst b/Doc/library/asyncio-api-index.rst
new file mode 100644
index 00000000000000..d5b5659abc65e2
--- /dev/null
+++ b/Doc/library/asyncio-api-index.rst
@@ -0,0 +1,218 @@
+.. currentmodule:: asyncio
+
+
+====================
+High-level API Index
+====================
+
+This page lists all high-level async/await enabled asyncio APIs.
+
+
+Tasks
+=====
+
+Utilities to run asyncio programs, create Tasks, and
+await on multiple things with timeouts.
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :func:`run`
+ - Create event loop, run a coroutine, close the loop.
+
+ * - :func:`create_task`
+ - Start an asyncio Task.
+
+ * - ``await`` :func:`sleep`
+ - Sleep for a number of seconds.
+
+ * - ``await`` :func:`gather`
+ - Schedule and wait for things concurrently.
+
+ * - ``await`` :func:`wait_for`
+ - Run with a timeout.
+
+ * - ``await`` :func:`shield`
+ - Shield from cancellation.
+
+ * - ``await`` :func:`wait`
+ - Monitor for completion.
+
+ * - :func:`current_task`
+ - Return the current Task.
+
+ * - :func:`all_tasks`
+ - Return all tasks for an event loop.
+
+ * - :class:`Task`
+ - Task object.
+
+ * - :func:`run_coroutine_threadsafe`
+ - Schedule a coroutine from another OS thread.
+
+ * - ``for in`` :func:`as_completed`
+ - Monitor for completion with a ``for`` loop.
+
+
+.. rubric:: Examples
+
+* :ref:`Using asyncio.gather() to run things in parallel
+ `.
+
+* :ref:`Using asyncio.wait_for() to enforce a timeout
+ `.
+
+* :ref:`Cancellation `.
+
+* :ref:`Using asyncio.sleep() `.
+
+* See also the main :ref:`Tasks documentation page `.
+
+
+Queues
+======
+
+Queues should be used to distribute work amongst multiple asyncio Tasks,
+implement connection pools, and pub/sub patterns.
+
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :class:`Queue`
+ - A FIFO queue.
+
+ * - :class:`PriorityQueue`
+ - A priority queue.
+
+ * - :class:`LifoQueue`
+ - A LIFO queue.
+
+
+.. rubric:: Examples
+
+* :ref:`Using asyncio.Queue to distribute workload between several
+ Tasks `.
+
+* See also the :ref:`Queues documentation page `.
+
+
+Subprocesses
+============
+
+Utilities to spawn subprocesses and run shell commands.
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - ``await`` :func:`create_subprocess_exec`
+ - Create a subprocess.
+
+ * - ``await`` :func:`create_subprocess_shell`
+ - Run a shell command.
+
+
+.. rubric:: Examples
+
+* :ref:`Executing a shell command `.
+
+* See also the :ref:`subprocess APIs `
+ documentation.
+
+
+Streams
+=======
+
+High-level APIs to work with network IO.
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - ``await`` :func:`open_connection`
+ - Establish a TCP connection.
+
+ * - ``await`` :func:`open_unix_connection`
+ - Establish a Unix socket connection.
+
+ * - ``await`` :func:`start_server`
+ - Start a TCP server.
+
+ * - ``await`` :func:`start_unix_server`
+ - Start a Unix socket server.
+
+ * - :class:`StreamReader`
+ - High-level async/await object to receive network data.
+
+ * - :class:`StreamWriter`
+ - High-level async/await object to send network data.
+
+
+.. rubric:: Examples
+
+* :ref:`Example TCP client `.
+
+* See also the :ref:`streams APIs `
+ documentation.
+
+
+Synchronization
+===============
+
+Threading-like synchronization primitives that can be used in Tasks.
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :class:`Lock`
+ - A mutex lock.
+
+ * - :class:`Event`
+ - An event object.
+
+ * - :class:`Condition`
+ - A condition object.
+
+ * - :class:`Semaphore`
+ - A semaphore.
+
+ * - :class:`BoundedSemaphore`
+ - A bounded semaphore.
+
+
+.. rubric:: Examples
+
+* :ref:`Using asyncio.Event `.
+
+* See also the documentation of asyncio
+ :ref:`synchronization primitives `.
+
+
+Exceptions
+==========
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+
+ * - :exc:`asyncio.TimeoutError`
+ - Raised on timeout by functions like :func:`wait_for`.
+ Keep in mind that ``asyncio.TimeoutError`` is **unrelated**
+ to the built-in :exc:`TimeoutError` exception.
+
+ * - :exc:`asyncio.CancelledError`
+ - Raised when a Task is cancelled. See also :meth:`Task.cancel`.
+
+
+.. rubric:: Examples
+
+* :ref:`Handling CancelledError to run code on cancellation request
+ `.
+
+* See also the full list of
+ :ref:`asyncio-specific exceptions `.
diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst
index 100fff561c5b1a..101e7817a95e98 100644
--- a/Doc/library/asyncio-dev.rst
+++ b/Doc/library/asyncio-dev.rst
@@ -2,415 +2,236 @@
.. _asyncio-dev:
-Develop with asyncio
-====================
+=======================
+Developing with asyncio
+=======================
-Asynchronous programming is different than classical "sequential" programming.
-This page lists common traps and explains how to avoid them.
+Asynchronous programming is different from classic "sequential"
+programming.
+This page lists common mistakes and traps and explains how
+to avoid them.
-.. _asyncio-debug-mode:
-
-Debug mode of asyncio
----------------------
-
-The implementation of :mod:`asyncio` has been written for performance.
-In order to ease the development of asynchronous code, you may wish to
-enable *debug mode*.
-To enable all debug checks for an application:
+.. _asyncio-debug-mode:
-* Enable the asyncio debug mode globally by setting the environment variable
- :envvar:`PYTHONASYNCIODEBUG` to ``1``, using ``-X dev`` command line option
- (see the :option:`-X` option), or by calling
- :meth:`AbstractEventLoop.set_debug`.
-* Set the log level of the :ref:`asyncio logger ` to
- :py:data:`logging.DEBUG`. For example, call
- ``logging.basicConfig(level=logging.DEBUG)`` at startup.
-* Configure the :mod:`warnings` module to display :exc:`ResourceWarning`
- warnings. For example, use the ``-Wdefault`` command line option of Python to
- display them.
+Debug Mode
+==========
-Examples debug checks:
+By default asyncio runs in production mode. In order to ease
+the development asyncio has a *debug mode*.
-* Log :ref:`coroutines defined but never "yielded from"
- `
-* :meth:`~AbstractEventLoop.call_soon` and :meth:`~AbstractEventLoop.call_at` methods
- raise an exception if they are called from the wrong thread.
-* Log the execution time of the selector
-* Log callbacks taking more than 100 ms to be executed. The
- :attr:`AbstractEventLoop.slow_callback_duration` attribute is the minimum
- duration in seconds of "slow" callbacks.
-* :exc:`ResourceWarning` warnings are emitted when transports and event loops
- are :ref:`not closed explicitly `.
+There are several ways to enable asyncio debug mode:
-.. versionchanged:: 3.7
+* Setting the :envvar:`PYTHONASYNCIODEBUG` environment variable to ``1``.
- The new ``-X dev`` command line option can now also be used to enable
- the debug mode.
+* Using the :option:`-X` ``dev`` Python command line option.
-.. seealso::
+* Passing ``debug=True`` to :func:`asyncio.run`.
- The :meth:`AbstractEventLoop.set_debug` method and the :ref:`asyncio logger
- `.
+* Calling :meth:`loop.set_debug`.
+In addition to enabling the debug mode, consider also:
-Cancellation
-------------
+* setting the log level of the :ref:`asyncio logger ` to
+ :py:data:`logging.DEBUG`, for example the following snippet of code
+ can be run at startup of the application::
-Cancellation of tasks is not common in classic programming. In asynchronous
-programming, not only is it something common, but you have to prepare your
-code to handle it.
+ logging.basicConfig(level=logging.DEBUG)
-Futures and tasks can be cancelled explicitly with their :meth:`Future.cancel`
-method. The :func:`wait_for` function cancels the waited task when the timeout
-occurs. There are many other cases where a task can be cancelled indirectly.
+* configuring the :mod:`warnings` module to display
+ :exc:`ResourceWarning` warnings. One way of doing that is by
+ using the :option:`-W` ``default`` command line option.
-Don't call :meth:`~Future.set_result` or :meth:`~Future.set_exception` method
-of :class:`Future` if the future is cancelled: it would fail with an exception.
-For example, write::
- if not fut.cancelled():
- fut.set_result('done')
+When the debug mode is enabled:
-Don't schedule directly a call to the :meth:`~Future.set_result` or the
-:meth:`~Future.set_exception` method of a future with
-:meth:`AbstractEventLoop.call_soon`: the future can be cancelled before its method
-is called.
+* asyncio checks for :ref:`coroutines that were not awaited
+ ` and logs them; this mitigates
+ the "forgotten await" pitfall.
-If you wait for a future, you should check early if the future was cancelled to
-avoid useless operations. Example::
+* Many non-threadsafe asyncio APIs (such as :meth:`loop.call_soon` and
+ :meth:`loop.call_at` methods) raise an exception if they are called
+ from a wrong thread.
- async def slow_operation(fut):
- if fut.cancelled():
- return
- # ... slow computation ...
- await fut
- # ...
+* The execution time of the I/O selector is logged if it takes too long to
+ perform an I/O operation.
-The :func:`shield` function can also be used to ignore cancellation.
+* Callbacks taking longer than 100ms are logged. The
+ :attr:`loop.slow_callback_duration` attribute can be used to set the
+ minimum execution duration in seconds that is considered "slow".
.. _asyncio-multithreading:
-Concurrency and multithreading
-------------------------------
+Concurrency and Multithreading
+==============================
-An event loop runs in a thread and executes all callbacks and tasks in the same
-thread. While a task is running in the event loop, no other task is running in
-the same thread. But when the task uses ``await``, the task is suspended
-and the event loop executes the next task.
+An event loop runs in a thread (typically the main thread) and executes
+all callbacks and Tasks in its thread. While a Task is running in the
+event loop, no other Tasks can run in the same thread. When a Task
+executes an ``await`` expression, the running Task gets suspended, and
+the event loop executes the next Task.
-To schedule a callback from a different thread, the
-:meth:`AbstractEventLoop.call_soon_threadsafe` method should be used. Example::
+To schedule a callback from a different OS thread, the
+:meth:`loop.call_soon_threadsafe` method should be used. Example::
loop.call_soon_threadsafe(callback, *args)
-Most asyncio objects are not thread safe. You should only worry if you access
-objects outside the event loop. For example, to cancel a future, don't call
-directly its :meth:`Future.cancel` method, but::
+Almost all asyncio objects are not thread safe, which is typically
+not a problem unless there is code that works with them from outside
+of a Task or a callback. If there's a need for such code to call a
+low-level asyncio API, the :meth:`loop.call_soon_threadsafe` method
+should be used, e.g.::
loop.call_soon_threadsafe(fut.cancel)
-To handle signals and to execute subprocesses, the event loop must be run in
-the main thread.
-
-To schedule a coroutine object from a different thread, the
+To schedule a coroutine object from a different OS thread, the
:func:`run_coroutine_threadsafe` function should be used. It returns a
:class:`concurrent.futures.Future` to access the result::
- future = asyncio.run_coroutine_threadsafe(coro_func(), loop)
- result = future.result(timeout) # Wait for the result with a timeout
-
-The :meth:`AbstractEventLoop.run_in_executor` method can be used with a thread pool
-executor to execute a callback in different thread to not block the thread of
-the event loop.
-
-.. seealso::
+ async def coro_func():
+ return await asyncio.sleep(1, 42)
- The :ref:`Synchronization primitives ` section describes ways
- to synchronize tasks.
+ # Later in another OS thread:
- The :ref:`Subprocess and threads ` section lists
- asyncio limitations to run subprocesses from different threads.
+ future = asyncio.run_coroutine_threadsafe(coro_func(), loop)
+ # Wait for the result:
+ result = future.result()
+To handle signals and to execute subprocesses, the event loop must be
+run in the main thread.
+The :meth:`loop.run_in_executor` method can be used with a
+:class:`concurrent.futures.ThreadPoolExecutor` to execute
+blocking code in a different OS thread without blocking the OS thread
+that the event loop runs in.
.. _asyncio-handle-blocking:
-Handle blocking functions correctly
------------------------------------
-
-Blocking functions should not be called directly. For example, if a function
-blocks for 1 second, other tasks are delayed by 1 second which can have an
-important impact on reactivity.
+Running Blocking Code
+=====================
-For networking and subprocesses, the :mod:`asyncio` module provides high-level
-APIs like :ref:`protocols `.
+Blocking (CPU-bound) code should not be called directly. For example,
+if a function performs a CPU-intensive calculation for 1 second,
+all concurrent asyncio Tasks and IO operations would be delayed
+by 1 second.
-An executor can be used to run a task in a different thread or even in a
-different process, to not block the thread of the event loop. See the
-:meth:`AbstractEventLoop.run_in_executor` method.
-
-.. seealso::
-
- The :ref:`Delayed calls ` section details how the
- event loop handles time.
+An executor can be used to run a task in a different thread or even in
+a different process to avoid blocking the OS thread with the
+event loop. See the :meth:`loop.run_in_executor` method for more
+details.
.. _asyncio-logger:
Logging
--------
-
-The :mod:`asyncio` module logs information with the :mod:`logging` module in
-the logger ``'asyncio'``.
+=======
-The default log level for the :mod:`asyncio` module is :py:data:`logging.INFO`.
-For those not wanting such verbosity from :mod:`asyncio` the log level can
-be changed. For example, to change the level to :py:data:`logging.WARNING`:
+asyncio uses the :mod:`logging` module and all logging is performed
+via the ``"asyncio"`` logger.
-.. code-block:: none
+The default log level is :py:data:`logging.INFO`, which can be easily
+adjusted::
- logging.getLogger('asyncio').setLevel(logging.WARNING)
+ logging.getLogger("asyncio").setLevel(logging.WARNING)
.. _asyncio-coroutine-not-scheduled:
-Detect coroutine objects never scheduled
-----------------------------------------
+Detect never-awaited coroutines
+===============================
-When a coroutine function is called and its result is not passed to
-:func:`ensure_future` or to the :meth:`AbstractEventLoop.create_task` method,
-the execution of the coroutine object will never be scheduled which is
-probably a bug. :ref:`Enable the debug mode of asyncio `
-to :ref:`log a warning ` to detect it.
-
-Example with the bug::
+When a coroutine function is called, but not awaited
+(e.g. ``coro()`` instead of ``await coro()``)
+or the coroutine is not scheduled with :meth:`asyncio.create_task`, asyncio
+will emit a :exc:`RuntimeWarning`::
import asyncio
async def test():
print("never scheduled")
+ async def main():
+ test()
+
+ asyncio.run(main())
+
+Output::
+
+ test.py:7: RuntimeWarning: coroutine 'test' was never awaited
test()
Output in debug mode::
- Coroutine test() at test.py:3 was never yielded from
- Coroutine object created at (most recent call last):
- File "test.py", line 7, in
- test()
+ test.py:7: RuntimeWarning: coroutine 'test' was never awaited
+ Coroutine created at (most recent call last)
+ File "../t.py", line 9, in
+ asyncio.run(main(), debug=True)
+
+ < .. >
-The fix is to call the :func:`ensure_future` function or the
-:meth:`AbstractEventLoop.create_task` method with the coroutine object.
+ File "../t.py", line 7, in main
+ test()
+ test()
-.. seealso::
+The usual fix is to either await the coroutine or call the
+:meth:`asyncio.create_task` function::
- :ref:`Pending task destroyed `.
+ async def main():
+ await test()
-Detect exceptions never consumed
---------------------------------
+Detect never-retrieved exceptions
+=================================
-Python usually calls :func:`sys.excepthook` on unhandled exceptions. If
-:meth:`Future.set_exception` is called, but the exception is never consumed,
-:func:`sys.excepthook` is not called. Instead, :ref:`a log is emitted
-` when the future is deleted by the garbage collector, with the
-traceback where the exception was raised.
+If a :meth:`Future.set_exception` is called but the Future object is
+never awaited on, the exception would never be propagated to the
+user code. In this case, asyncio would emit a log message when the
+Future object is garbage collected.
-Example of unhandled exception::
+Example of an unhandled exception::
import asyncio
- @asyncio.coroutine
- def bug():
+ async def bug():
raise Exception("not consumed")
- loop = asyncio.get_event_loop()
- asyncio.ensure_future(bug())
- loop.run_forever()
- loop.close()
+ async def main():
+ asyncio.create_task(bug())
+
+ asyncio.run(main())
Output::
Task exception was never retrieved
- future: exception=Exception('not consumed',)>
- Traceback (most recent call last):
- File "asyncio/tasks.py", line 237, in _step
- result = next(coro)
- File "asyncio/coroutines.py", line 141, in coro
- res = func(*args, **kw)
- File "test.py", line 5, in bug
- raise Exception("not consumed")
- Exception: not consumed
-
-:ref:`Enable the debug mode of asyncio ` to get the
-traceback where the task was created. Output in debug mode::
+ future:
+ exception=Exception('not consumed')>
- Task exception was never retrieved
- future: exception=Exception('not consumed',) created at test.py:8>
- source_traceback: Object created at (most recent call last):
- File "test.py", line 8, in
- asyncio.ensure_future(bug())
Traceback (most recent call last):
- File "asyncio/tasks.py", line 237, in _step
- result = next(coro)
- File "asyncio/coroutines.py", line 79, in __next__
- return next(self.gen)
- File "asyncio/coroutines.py", line 141, in coro
- res = func(*args, **kw)
- File "test.py", line 5, in bug
+ File "test.py", line 4, in bug
raise Exception("not consumed")
Exception: not consumed
-There are different options to fix this issue. The first option is to chain the
-coroutine in another coroutine and use classic try/except::
-
- async def handle_exception():
- try:
- await bug()
- except Exception:
- print("exception consumed")
-
- loop = asyncio.get_event_loop()
- asyncio.ensure_future(handle_exception())
- loop.run_forever()
- loop.close()
-
-Another option is to use the :meth:`AbstractEventLoop.run_until_complete`
-function::
-
- task = asyncio.ensure_future(bug())
- try:
- loop.run_until_complete(task)
- except Exception:
- print("exception consumed")
-
-.. seealso::
-
- The :meth:`Future.exception` method.
-
-
-Chain coroutines correctly
---------------------------
-
-When a coroutine function calls other coroutine functions and tasks, they
-should be chained explicitly with ``await``. Otherwise, the execution is
-not guaranteed to be sequential.
+:ref:`Enable the debug mode ` to get the
+traceback where the task was created::
-Example with different bugs using :func:`asyncio.sleep` to simulate slow
-operations::
+ asyncio.run(main(), debug=True)
- import asyncio
-
- async def create():
- await asyncio.sleep(3.0)
- print("(1) create file")
-
- async def write():
- await asyncio.sleep(1.0)
- print("(2) write into file")
-
- async def close():
- print("(3) close file")
-
- async def test():
- asyncio.ensure_future(create())
- asyncio.ensure_future(write())
- asyncio.ensure_future(close())
- await asyncio.sleep(2.0)
- loop.stop()
-
- loop = asyncio.get_event_loop()
- asyncio.ensure_future(test())
- loop.run_forever()
- print("Pending tasks at exit: %s" % asyncio.Task.all_tasks(loop))
- loop.close()
-
-Expected output:
-
-.. code-block:: none
-
- (1) create file
- (2) write into file
- (3) close file
- Pending tasks at exit: set()
-
-Actual output:
-
-.. code-block:: none
-
- (3) close file
- (2) write into file
- Pending tasks at exit: {>}
- Task was destroyed but it is pending!
- task: >
-
-The loop stopped before the ``create()`` finished, ``close()`` has been called
-before ``write()``, whereas coroutine functions were called in this order:
-``create()``, ``write()``, ``close()``.
-
-To fix the example, tasks must be marked with ``await``::
-
- async def test():
- await asyncio.ensure_future(create())
- await asyncio.ensure_future(write())
- await asyncio.ensure_future(close())
- await asyncio.sleep(2.0)
- loop.stop()
-
-Or without ``asyncio.ensure_future()``::
-
- async def test():
- await create()
- await write()
- await close()
- await asyncio.sleep(2.0)
- loop.stop()
-
-
-.. _asyncio-pending-task-destroyed:
-
-Pending task destroyed
-----------------------
-
-If a pending task is destroyed, the execution of its wrapped :ref:`coroutine
-` did not complete. It is probably a bug and so a warning is logged.
-
-Example of log:
-
-.. code-block:: none
-
- Task was destroyed but it is pending!
- task: wait_for=>
-
-:ref:`Enable the debug mode of asyncio ` to get the
-traceback where the task was created. Example of log in debug mode:
+Output in debug mode::
-.. code-block:: none
+ Task exception was never retrieved
+ future:
+ exception=Exception('not consumed') created at asyncio/tasks.py:321>
- Task was destroyed but it is pending!
source_traceback: Object created at (most recent call last):
- File "test.py", line 15, in
- task = asyncio.ensure_future(coro, loop=loop)
- task: wait_for= created at test.py:15>
-
-
-.. seealso::
-
- :ref:`Detect coroutine objects never scheduled `.
-
-.. _asyncio-close-transports:
+ File "../t.py", line 9, in
+ asyncio.run(main(), debug=True)
-Close transports and event loops
---------------------------------
+ < .. >
-When a transport is no more needed, call its ``close()`` method to release
-resources. Event loops must also be closed explicitly.
-
-If a transport or an event loop is not closed explicitly, a
-:exc:`ResourceWarning` warning will be emitted in its destructor. By default,
-:exc:`ResourceWarning` warnings are ignored. The :ref:`Debug mode of asyncio
-` section explains how to display them.
+ Traceback (most recent call last):
+ File "../t.py", line 4, in bug
+ raise Exception("not consumed")
+ Exception: not consumed
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 5f915c5c43921a..97c1078022601b 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -1,103 +1,165 @@
.. currentmodule:: asyncio
-.. _asyncio-event-loop:
-Base Event Loop
-===============
+==========
+Event Loop
+==========
-**Source code:** :source:`Lib/asyncio/events.py`
-The event loop is the central execution device provided by :mod:`asyncio`.
-It provides multiple facilities, including:
+.. rubric:: Preface
-* Registering, executing and cancelling delayed calls (timeouts).
+The event loop is the core of every asyncio application.
+Event loops run asynchronous tasks and callbacks, perform network
+IO operations, and run subprocesses.
-* Creating client and server :ref:`transports ` for various
- kinds of communication.
+Application developers should typically use the high-level asyncio functions,
+such as :func:`asyncio.run`, and should rarely need to reference the loop
+object or call its methods. This section is intended mostly for authors
+of lower-level code, libraries, and frameworks, who need finer control over
+the event loop behavior.
-* Launching subprocesses and the associated :ref:`transports
- ` for communication with an external program.
+.. rubric:: Obtaining the Event Loop
-* Delegating costly function calls to a pool of threads.
+The following low-level functions can be used to get, set, or create
+an event loop:
-.. class:: BaseEventLoop
+.. function:: get_running_loop()
- This class is an implementation detail. It is a subclass of
- :class:`AbstractEventLoop` and may be a base class of concrete
- event loop implementations found in :mod:`asyncio`. It should not
- be used directly; use :class:`AbstractEventLoop` instead.
- ``BaseEventLoop`` should not be subclassed by third-party code; the
- internal interface is not stable.
+ Return the running event loop in the current OS thread.
-.. class:: AbstractEventLoop
+ If there is no running event loop a :exc:`RuntimeError` is raised.
+ This function can only be called from a coroutine or a callback.
- Abstract base class of event loops.
+ .. versionadded:: 3.7
- This class is :ref:`not thread safe `.
+.. function:: get_event_loop()
-Run an event loop
------------------
+ Get the current event loop.
-.. method:: AbstractEventLoop.run_forever()
+ If there is no current event loop set in the current OS thread,
+ the OS thread is main, and :func:`set_event_loop` has not yet
+ been called, asyncio will create a new event loop and set it as the
+ current one.
- Run until :meth:`stop` is called. If :meth:`stop` is called before
- :meth:`run_forever()` is called, this polls the I/O selector once
- with a timeout of zero, runs all callbacks scheduled in response to
- I/O events (and those that were already scheduled), and then exits.
- If :meth:`stop` is called while :meth:`run_forever` is running,
- this will run the current batch of callbacks and then exit. Note
- that callbacks scheduled by callbacks will not run in that case;
- they will run the next time :meth:`run_forever` is called.
+ Because this function has rather complex behavior (especially
+ when custom event loop policies are in use), using the
+ :func:`get_running_loop` function is preferred to :func:`get_event_loop`
+ in coroutines and callbacks.
- .. versionchanged:: 3.5.1
+ Consider also using the :func:`asyncio.run` function instead of using
+ lower level functions to manually create and close an event loop.
-.. method:: AbstractEventLoop.run_until_complete(future)
+.. function:: set_event_loop(loop)
- Run until the :class:`Future` is done.
+ Set *loop* as a current event loop for the current OS thread.
- If the argument is a :ref:`coroutine object `, it is wrapped by
- :func:`ensure_future`.
+.. function:: new_event_loop()
- Return the Future's result, or raise its exception.
+ Create a new event loop object.
-.. method:: AbstractEventLoop.is_running()
+Note that the behaviour of :func:`get_event_loop`, :func:`set_event_loop`,
+and :func:`new_event_loop` functions can be altered by
+:ref:`setting a custom event loop policy `.
- Returns running status of event loop.
-.. method:: AbstractEventLoop.stop()
+.. rubric:: Contents
- Stop running the event loop.
+This documentation page contains the following sections:
- This causes :meth:`run_forever` to exit at the next suitable
- opportunity (see there for more details).
+* The `Event Loop Methods`_ section is the reference documentation of
+ the event loop APIs;
- .. versionchanged:: 3.5.1
+* The `Callback Handles`_ section documents the :class:`Handle` and
+ :class:`TimerHandle` instances which are returned from scheduling
+ methods such as :meth:`loop.call_soon` and :meth:`loop.call_later`;
+
+* The `Server Objects`_ section documents types returned from
+ event loop methods like :meth:`loop.create_server`;
+
+* The `Event Loop Implementations`_ section documents the
+ :class:`SelectorEventLoop` and :class:`ProactorEventLoop` classes;
+
+* The `Examples`_ section showcases how to work with some event
+ loop APIs.
+
+
+.. _asyncio-event-loop:
+
+Event Loop Methods
+==================
+
+Event loops have **low-level** APIs for the following:
+
+.. contents::
+ :depth: 1
+ :local:
+
+
+Running and stopping the loop
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. method:: loop.run_until_complete(future)
+
+ Run until the *future* (an instance of :class:`Future`) has
+ completed.
+
+ If the argument is a :ref:`coroutine object ` it
+ is implicitly scheduled to run as a :class:`asyncio.Task`.
+
+ Return the Future's result or raise its exception.
+
+.. method:: loop.run_forever()
+
+ Run the event loop until :meth:`stop` is called.
+
+ If :meth:`stop` is called before :meth:`run_forever()` is called,
+ the loop will poll the I/O selector once with a timeout of zero,
+ run all callbacks scheduled in response to I/O events (and
+ those that were already scheduled), and then exit.
+
+ If :meth:`stop` is called while :meth:`run_forever` is running,
+ the loop will run the current batch of callbacks and then exit.
+ Note that new callbacks scheduled by callbacks will not run in this
+ case; instead, they will run the next time :meth:`run_forever` or
+ :meth:`run_until_complete` is called.
+
+.. method:: loop.stop()
+
+ Stop the event loop.
+
+.. method:: loop.is_running()
-.. method:: AbstractEventLoop.is_closed()
+ Return ``True`` if the event loop is currently running.
- Returns ``True`` if the event loop was closed.
+.. method:: loop.is_closed()
- .. versionadded:: 3.4.2
+ Return ``True`` if the event loop was closed.
-.. method:: AbstractEventLoop.close()
+.. method:: loop.close()
- Close the event loop. The loop must not be running. Pending
- callbacks will be lost.
+ Close the event loop.
- This clears the queues and shuts down the executor, but does not wait for
- the executor to finish.
+ The loop must not be running when this function is called.
+ Any pending callbacks will be discarded.
- This is idempotent and irreversible. No other methods should be called after
- this one.
+ This method clears all queues and shuts down the executor, but does
+ not wait for the executor to finish.
+ This method is idempotent and irreversible. No other methods
+ should be called after the event loop is closed.
-.. coroutinemethod:: AbstractEventLoop.shutdown_asyncgens()
+.. coroutinemethod:: loop.shutdown_asyncgens()
Schedule all currently open :term:`asynchronous generator` objects to
close with an :meth:`~agen.aclose()` call. After calling this method,
- the event loop will issue a warning whenever a new asynchronous generator
- is iterated. Should be used to finalize all scheduled asynchronous
- generators reliably. Example::
+ the event loop will issue a warning if a new asynchronous generator
+ is iterated. This should be used to reliably finalize all scheduled
+ asynchronous generators.
+
+ Note that there is no need to call this function when
+ :func:`asyncio.run` is used.
+
+ Example::
try:
loop.run_forever()
@@ -108,208 +170,223 @@ Run an event loop
.. versionadded:: 3.6
-.. _asyncio-pass-keywords:
-
-Calls
------
-
-Most :mod:`asyncio` functions don't accept keywords. If you want to pass
-keywords to your callback, use :func:`functools.partial`. For example,
-``loop.call_soon(functools.partial(print, "Hello", flush=True))`` will call
-``print("Hello", flush=True)``.
-
-.. note::
- :func:`functools.partial` is better than ``lambda`` functions, because
- :mod:`asyncio` can inspect :func:`functools.partial` object to display
- parameters in debug mode, whereas ``lambda`` functions have a poor
- representation.
+Scheduling callbacks
+^^^^^^^^^^^^^^^^^^^^
-.. method:: AbstractEventLoop.call_soon(callback, \*args)
+.. method:: loop.call_soon(callback, *args, context=None)
- Arrange for a callback to be called as soon as possible. The callback is
- called after :meth:`call_soon` returns, when control returns to the event
- loop.
+ Schedule a *callback* to be called with *args* arguments at
+ the next iteration of the event loop.
- This operates as a :abbr:`FIFO (first-in, first-out)` queue, callbacks
- are called in the order in which they are registered. Each callback
- will be called exactly once.
+ Callbacks are called in the order in which they are registered.
+ Each callback will be called exactly once.
- Any positional arguments after the callback will be passed to the
- callback when it is called.
+ An optional keyword-only *context* argument allows specifying a
+ custom :class:`contextvars.Context` for the *callback* to run in.
+ The current context is used when no *context* is provided.
An instance of :class:`asyncio.Handle` is returned, which can be
- used to cancel the callback.
+ used later to cancel the callback.
- :ref:`Use functools.partial to pass keywords to the callback
- `.
+ This method is not thread-safe.
-.. method:: AbstractEventLoop.call_soon_threadsafe(callback, \*args)
+.. method:: loop.call_soon_threadsafe(callback, *args, context=None)
- Like :meth:`call_soon`, but thread safe.
+ A thread-safe variant of :meth:`call_soon`. Must be used to
+ schedule callbacks *from another thread*.
See the :ref:`concurrency and multithreading `
section of the documentation.
+.. versionchanged:: 3.7
+ The *context* keyword-only parameter was added. See :pep:`567`
+ for more details.
+
+.. _asyncio-pass-keywords:
+
+.. note::
+
+ Most :mod:`asyncio` scheduling functions don't allow passing
+ keyword arguments. To do that, use :func:`functools.partial`::
+
+ # will schedule "print("Hello", flush=True)"
+ loop.call_soon(
+ functools.partial(print, "Hello", flush=True))
+
+ Using partial objects is usually more convenient than using lambdas,
+ as asyncio can render partial objects better in debug and error
+ messages.
+
.. _asyncio-delayed-calls:
-Delayed calls
--------------
+Scheduling delayed callbacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The event loop has its own internal clock for computing timeouts.
-Which clock is used depends on the (platform-specific) event loop
-implementation; ideally it is a monotonic clock. This will generally be
-a different clock than :func:`time.time`.
+Event loop provides mechanisms to schedule callback functions
+to be called at some point in the future. Event loop uses monotonic
+clocks to track time.
-.. note::
- Timeouts (relative *delay* or absolute *when*) should not exceed one day.
+.. method:: loop.call_later(delay, callback, *args, context=None)
+ Schedule *callback* to be called after the given *delay*
+ number of seconds (can be either an int or a float).
-.. method:: AbstractEventLoop.call_later(delay, callback, *args)
+ An instance of :class:`asyncio.TimerHandle` is returned which can
+ be used to cancel the callback.
- Arrange for the *callback* to be called after the given *delay*
- seconds (either an int or float).
+ *callback* will be called exactly once. If two callbacks are
+ scheduled for exactly the same time, the order in which they
+ are called is undefined.
- An instance of :class:`asyncio.Handle` is returned, which can be
- used to cancel the callback.
+ The optional positional *args* will be passed to the callback when
+ it is called. If you want the callback to be called with keyword
+ arguments use :func:`functools.partial`.
- *callback* will be called exactly once per call to :meth:`call_later`.
- If two callbacks are scheduled for exactly the same time, it is
- undefined which will be called first.
+ An optional keyword-only *context* argument allows specifying a
+ custom :class:`contextvars.Context` for the *callback* to run in.
+ The current context is used when no *context* is provided.
- The optional positional *args* will be passed to the callback when it
- is called. If you want the callback to be called with some named
- arguments, use a closure or :func:`functools.partial`.
+ .. versionchanged:: 3.7
+ The *context* keyword-only parameter was added. See :pep:`567`
+ for more details.
- :ref:`Use functools.partial to pass keywords to the callback
- `.
+ .. versionchanged:: 3.7.1
+ In Python 3.7.0 and earlier with the default event loop implementation,
+ the *delay* could not exceed one day.
+ This has been fixed in Python 3.7.1.
-.. method:: AbstractEventLoop.call_at(when, callback, *args)
+.. method:: loop.call_at(when, callback, *args, context=None)
- Arrange for the *callback* to be called at the given absolute timestamp
- *when* (an int or float), using the same time reference as
- :meth:`AbstractEventLoop.time`.
+ Schedule *callback* to be called at the given absolute timestamp
+ *when* (an int or a float), using the same time reference as
+ :meth:`loop.time`.
This method's behavior is the same as :meth:`call_later`.
- An instance of :class:`asyncio.Handle` is returned, which can be
- used to cancel the callback.
+ An instance of :class:`asyncio.TimerHandle` is returned which can
+ be used to cancel the callback.
- :ref:`Use functools.partial to pass keywords to the callback
- `.
+ .. versionchanged:: 3.7
+ The *context* keyword-only parameter was added. See :pep:`567`
+ for more details.
+
+ .. versionchanged:: 3.7.1
+ In Python 3.7.0 and earlier with the default event loop implementation,
+ the difference between *when* and the current time could not exceed
+ one day. This has been fixed in Python 3.7.1.
-.. method:: AbstractEventLoop.time()
+.. method:: loop.time()
- Return the current time, as a :class:`float` value, according to the
- event loop's internal clock.
+ Return the current time, as a :class:`float` value, according to
+ the event loop's internal monotonic clock.
+
+.. note::
+ .. versionchanged:: 3.8
+ In Python 3.7 and earlier timeouts (relative *delay* or absolute *when*)
+ should not exceed one day. This has been fixed in Python 3.8.
.. seealso::
The :func:`asyncio.sleep` function.
-Futures
--------
+Creating Futures and Tasks
+^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. method:: AbstractEventLoop.create_future()
+.. method:: loop.create_future()
- Create an :class:`asyncio.Future` object attached to the loop.
+ Create an :class:`asyncio.Future` object attached to the event loop.
- This is a preferred way to create futures in asyncio, as event
- loop implementations can provide alternative implementations
- of the Future class (with better performance or instrumentation).
+ This is the preferred way to create Futures in asyncio. This lets
+ third-party event loops provide alternative implementations of
+ the Future object (with better performance or instrumentation).
.. versionadded:: 3.5.2
+.. method:: loop.create_task(coro)
-Tasks
------
-
-.. method:: AbstractEventLoop.create_task(coro)
-
- Schedule the execution of a :ref:`coroutine object `: wrap it in
- a future. Return a :class:`Task` object.
-
- Third-party event loops can use their own subclass of :class:`Task` for
- interoperability. In this case, the result type is a subclass of
- :class:`Task`.
+ Schedule the execution of a :ref:`coroutine`.
+ Return a :class:`Task` object.
- .. versionadded:: 3.4.2
+ Third-party event loops can use their own subclass of :class:`Task`
+ for interoperability. In this case, the result type is a subclass
+ of :class:`Task`.
-.. method:: AbstractEventLoop.set_task_factory(factory)
+.. method:: loop.set_task_factory(factory)
Set a task factory that will be used by
- :meth:`AbstractEventLoop.create_task`.
+ :meth:`loop.create_task`.
If *factory* is ``None`` the default task factory will be set.
+ Otherwise, *factory* must be a *callable* with the signature matching
+ ``(loop, coro)``, where *loop* is a reference to the active
+ event loop, and *coro* is a coroutine object. The callable
+ must return a :class:`asyncio.Future`-compatible object.
- If *factory* is a *callable*, it should have a signature matching
- ``(loop, coro)``, where *loop* will be a reference to the active
- event loop, *coro* will be a coroutine object. The callable
- must return an :class:`asyncio.Future` compatible object.
+.. method:: loop.get_task_factory()
- .. versionadded:: 3.4.4
+ Return a task factory or ``None`` if the default one is in use.
-.. method:: AbstractEventLoop.get_task_factory()
- Return a task factory, or ``None`` if the default one is in use.
+Opening network connections
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
- .. versionadded:: 3.4.4
+.. coroutinemethod:: loop.create_connection(protocol_factory, \
+ host=None, port=None, \*, ssl=None, \
+ family=0, proto=0, flags=0, sock=None, \
+ local_addr=None, server_hostname=None, \
+ ssl_handshake_timeout=None)
+ Open a streaming transport connection to a given
+ address specified by *host* and *port*.
-Creating connections
---------------------
+ The socket family can be either :py:data:`~socket.AF_INET` or
+ :py:data:`~socket.AF_INET6` depending on *host* (or the *family*
+ argument, if provided).
-.. coroutinemethod:: AbstractEventLoop.create_connection(protocol_factory, host=None, port=None, \*, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None)
+ The socket type will be :py:data:`~socket.SOCK_STREAM`.
- Create a streaming transport connection to a given Internet *host* and
- *port*: socket family :py:data:`~socket.AF_INET` or
- :py:data:`~socket.AF_INET6` depending on *host* (or *family* if specified),
- socket type :py:data:`~socket.SOCK_STREAM`. *protocol_factory* must be a
- callable returning a :ref:`protocol ` instance.
+ *protocol_factory* must be a callable returning an
+ :ref:`asyncio protocol ` implementation.
This method will try to establish the connection in the background.
When successful, it returns a ``(transport, protocol)`` pair.
The chronological synopsis of the underlying operation is as follows:
- #. The connection is established, and a :ref:`transport `
- is created to represent it.
+ #. The connection is established and a :ref:`transport `
+ is created for it.
- #. *protocol_factory* is called without arguments and must return a
- :ref:`protocol ` instance.
+ #. *protocol_factory* is called without arguments and is expected to
+ return a :ref:`protocol ` instance.
- #. The protocol instance is tied to the transport, and its
- :meth:`connection_made` method is called.
+ #. The protocol instance is coupled with the transport by calling its
+ :meth:`~BaseProtocol.connection_made` method.
- #. The coroutine returns successfully with the ``(transport, protocol)``
- pair.
+ #. A ``(transport, protocol)`` tuple is returned on success.
- The created transport is an implementation-dependent bidirectional stream.
+ The created transport is an implementation-dependent bidirectional
+ stream.
- .. note::
- *protocol_factory* can be any kind of callable, not necessarily
- a class. For example, if you want to use a pre-created
- protocol instance, you can pass ``lambda: my_protocol``.
-
- Options that change how the connection is created:
+ Other arguments:
* *ssl*: if given and not false, a SSL/TLS transport is created
(by default a plain TCP transport is created). If *ssl* is
a :class:`ssl.SSLContext` object, this context is used to create
- the transport; if *ssl* is :const:`True`, a context with some
- unspecified default settings is used.
+ the transport; if *ssl* is :const:`True`, a default context returned
+ from :func:`ssl.create_default_context` is used.
.. seealso:: :ref:`SSL/TLS security considerations `
- * *server_hostname*, is only for use together with *ssl*,
- and sets or overrides the hostname that the target server's certificate
- will be matched against. By default the value of the *host* argument
+ * *server_hostname* sets or overrides the hostname that the target
+ server's certificate will be matched against. Should only be passed
+ if *ssl* is not ``None``. By default the value of the *host* argument
is used. If *host* is empty, there is no default and you must pass a
value for *server_hostname*. If *server_hostname* is an empty
string, hostname matching is disabled (which is a serious security
- risk, allowing for man-in-the-middle-attacks).
+ risk, allowing for potential man-in-the-middle attacks).
* *family*, *proto*, *flags* are the optional address family, protocol
and flags to be passed through to getaddrinfo() for *host* resolution.
@@ -323,38 +400,66 @@ Creating connections
* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
to bind the socket to locally. The *local_host* and *local_port*
- are looked up using getaddrinfo(), similarly to *host* and *port*.
+ are looked up using ``getaddrinfo()``, similarly to *host* and *port*.
- * *ssl_handshake_timeout* is (for an SSL connection) the time in seconds
- to wait for the SSL handshake to complete before aborting the connection.
- ``10.0`` seconds if ``None`` (default).
+ * *ssl_handshake_timeout* is (for a TLS connection) the time in seconds
+ to wait for the TLS handshake to complete before aborting the connection.
+ ``60.0`` seconds if ``None`` (default).
.. versionadded:: 3.7
The *ssl_handshake_timeout* parameter.
+ .. versionchanged:: 3.6
+
+ The socket option :py:data:`~socket.TCP_NODELAY` is set by default
+ for all TCP connections.
+
.. versionchanged:: 3.5
- On Windows with :class:`ProactorEventLoop`, SSL/TLS is now supported.
+ Added support for SSL/TLS in :class:`ProactorEventLoop`.
.. seealso::
- The :func:`open_connection` function can be used to get a pair of
- (:class:`StreamReader`, :class:`StreamWriter`) instead of a protocol.
+ The :func:`open_connection` function is a high-level alternative
+ API. It returns a pair of (:class:`StreamReader`, :class:`StreamWriter`)
+ that can be used directly in async/await code.
+.. coroutinemethod:: loop.create_datagram_endpoint(protocol_factory, \
+ local_addr=None, remote_addr=None, \*, \
+ family=0, proto=0, flags=0, \
+ reuse_address=None, reuse_port=None, \
+ allow_broadcast=None, sock=None)
-.. coroutinemethod:: AbstractEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, \*, family=0, proto=0, flags=0, reuse_address=None, reuse_port=None, allow_broadcast=None, sock=None)
+ .. note::
+ The parameter *reuse_address* is no longer supported, as using
+ :py:data:`~sockets.SO_REUSEADDR` poses a significant security concern for
+ UDP. Explicitly passing ``reuse_address=True`` will raise an exception.
- Create datagram connection: socket family :py:data:`~socket.AF_INET`,
- :py:data:`~socket.AF_INET6` or :py:data:`~socket.AF_UNIX` depending on
- *host* (or *family* if specified), socket type
- :py:data:`~socket.SOCK_DGRAM`. *protocol_factory* must be a
- callable returning a :ref:`protocol ` instance.
+ When multiple processes with differing UIDs assign sockets to an
+ indentical UDP socket address with ``SO_REUSEADDR``, incoming packets can
+ become randomly distributed among the sockets.
- This method will try to establish the connection in the background.
- When successful, the it returns a ``(transport, protocol)`` pair.
+ For supported platforms, *reuse_port* can be used as a replacement for
+ similar functionality. With *reuse_port*,
+ :py:data:`~sockets.SO_REUSEPORT` is used instead, which specifically
+ prevents processes with differing UIDs from assigning sockets to the same
+ socket address.
+
+ Create a datagram connection.
- Options changing how the connection is created:
+ The socket family can be either :py:data:`~socket.AF_INET`,
+ :py:data:`~socket.AF_INET6`, or :py:data:`~socket.AF_UNIX`,
+ depending on *host* (or the *family* argument, if provided).
+
+ The socket type will be :py:data:`~socket.SOCK_DGRAM`.
+
+ *protocol_factory* must be a callable returning a
+ :ref:`protocol ` implementation.
+
+ A tuple of ``(transport, protocol)`` is returned on success.
+
+ Other arguments:
* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
to bind the socket to locally. The *local_host* and *local_port*
@@ -369,15 +474,10 @@ Creating connections
resolution. If given, these should all be integers from the
corresponding :mod:`socket` module constants.
- * *reuse_address* tells the kernel to reuse a local socket in
- TIME_WAIT state, without waiting for its natural timeout to
- expire. If not specified will automatically be set to ``True`` on
- UNIX.
-
* *reuse_port* tells the kernel to allow this endpoint to be bound to the
same port as other existing endpoints are bound to, so long as they all
set this flag when being created. This option is not supported on Windows
- and some UNIX's. If the :py:data:`~socket.SO_REUSEPORT` constant is not
+ and some Unixes. If the :py:data:`~socket.SO_REUSEPORT` constant is not
defined then this capability is unsupported.
* *allow_broadcast* tells the kernel to allow this endpoint to send
@@ -388,29 +488,39 @@ Creating connections
transport. If specified, *local_addr* and *remote_addr* should be omitted
(must be :const:`None`).
- On Windows with :class:`ProactorEventLoop`, this method is not supported.
+ On Windows, with :class:`ProactorEventLoop`, this method is not supported.
See :ref:`UDP echo client protocol ` and
:ref:`UDP echo server protocol ` examples.
+ .. versionchanged:: 3.4.4
+ The *family*, *proto*, *flags*, *reuse_address*, *reuse_port,
+ *allow_broadcast*, and *sock* parameters were added.
-.. coroutinemethod:: AbstractEventLoop.create_unix_connection(protocol_factory, path=None, \*, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None)
+ .. versionchanged:: 3.7.6
+ The *reuse_address* parameter is no longer supported due to security
+ concerns.
- Create UNIX connection: socket family :py:data:`~socket.AF_UNIX`, socket
- type :py:data:`~socket.SOCK_STREAM`. The :py:data:`~socket.AF_UNIX` socket
- family is used to communicate between processes on the same machine
- efficiently.
+.. coroutinemethod:: loop.create_unix_connection(protocol_factory, \
+ path=None, \*, ssl=None, sock=None, \
+ server_hostname=None, ssl_handshake_timeout=None)
- This method will try to establish the connection in the background.
- When successful, the it returns a ``(transport, protocol)`` pair.
+ Create a Unix connection.
+
+ The socket family will be :py:data:`~socket.AF_UNIX`; socket
+ type will be :py:data:`~socket.SOCK_STREAM`.
- *path* is the name of a UNIX domain socket, and is required unless a *sock*
- parameter is specified. Abstract UNIX sockets, :class:`str`,
- :class:`bytes`, and :class:`~pathlib.Path` paths are supported.
+ A tuple of ``(transport, protocol)`` is returned on success.
- See the :meth:`AbstractEventLoop.create_connection` method for parameters.
+ *path* is the name of a Unix domain socket and is required,
+ unless a *sock* parameter is specified. Abstract Unix sockets,
+ :class:`str`, :class:`bytes`, and :class:`~pathlib.Path` paths are
+ supported.
- Availability: UNIX.
+ See the documentation of the :meth:`loop.create_connection` method
+ for information about arguments to this method.
+
+ .. availability:: Unix.
.. versionadded:: 3.7
@@ -418,59 +528,72 @@ Creating connections
.. versionchanged:: 3.7
- The *path* parameter can now be a :class:`~pathlib.Path` object.
+ The *path* parameter can now be a :term:`path-like object`.
-Creating listening connections
-------------------------------
+Creating network servers
+^^^^^^^^^^^^^^^^^^^^^^^^
-.. coroutinemethod:: AbstractEventLoop.create_server(protocol_factory, host=None, port=None, \*, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, start_serving=True)
+.. coroutinemethod:: loop.create_server(protocol_factory, \
+ host=None, port=None, \*, \
+ family=socket.AF_UNSPEC, \
+ flags=socket.AI_PASSIVE, \
+ sock=None, backlog=100, ssl=None, \
+ reuse_address=None, reuse_port=None, \
+ ssl_handshake_timeout=None, start_serving=True)
- Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) bound to
- *host* and *port*.
+ Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) listening
+ on *port* of the *host* address.
- Return a :class:`Server` object, its :attr:`~Server.sockets` attribute
- contains created sockets. Use the :meth:`Server.close` method to stop the
- server: close listening sockets.
+ Returns a :class:`Server` object.
- Parameters:
+ Arguments:
+
+ * *protocol_factory* must be a callable returning a
+ :ref:`protocol ` implementation.
+
+ * The *host* parameter can be set to several types which determine where
+ the server would be listening:
- * The *host* parameter can be a string, in that case the TCP server is
- bound to *host* and *port*. The *host* parameter can also be a sequence
- of strings and in that case the TCP server is bound to all hosts of the
- sequence. If *host* is an empty string or ``None``, all interfaces are
- assumed and a list of multiple sockets will be returned (most likely one
- for IPv4 and another one for IPv6).
+ - If *host* is a string, the TCP server is bound to a single network
+ interface specified by *host*.
+
+ - If *host* is a sequence of strings, the TCP server is bound to all
+ network interfaces specified by the sequence.
+
+ - If *host* is an empty string or ``None``, all interfaces are
+ assumed and a list of multiple sockets will be returned (most likely
+ one for IPv4 and another one for IPv6).
* *family* can be set to either :data:`socket.AF_INET` or
- :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. If not set
- it will be determined from host (defaults to :data:`socket.AF_UNSPEC`).
+ :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6.
+ If not set, the *family* will be determined from host name
+ (defaults to :data:`~socket.AF_UNSPEC`).
* *flags* is a bitmask for :meth:`getaddrinfo`.
* *sock* can optionally be specified in order to use a preexisting
- socket object. If specified, *host* and *port* should be omitted (must be
- :const:`None`).
+ socket object. If specified, *host* and *port* must not be specified.
* *backlog* is the maximum number of queued connections passed to
:meth:`~socket.socket.listen` (defaults to 100).
- * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over the
- accepted connections.
+ * *ssl* can be set to an :class:`~ssl.SSLContext` instance to enable
+ TLS over the accepted connections.
* *reuse_address* tells the kernel to reuse a local socket in
- TIME_WAIT state, without waiting for its natural timeout to
+ ``TIME_WAIT`` state, without waiting for its natural timeout to
expire. If not specified will automatically be set to ``True`` on
- UNIX.
+ Unix.
* *reuse_port* tells the kernel to allow this endpoint to be bound to the
same port as other existing endpoints are bound to, so long as they all
set this flag when being created. This option is not supported on
Windows.
- * *ssl_handshake_timeout* is (for an SSL server) the time in seconds to wait
- for the SSL handshake to complete before aborting the connection.
- ``10.0`` seconds if ``None`` (default).
+ * *ssl_handshake_timeout* is (for a TLS server) the time in seconds to wait
+ for the TLS handshake to complete before aborting the connection.
+ ``60.0`` seconds if ``None`` (default).
* *start_serving* set to ``True`` (the default) causes the created server
to start accepting connections immediately. When set to ``False``,
@@ -480,61 +603,77 @@ Creating listening connections
.. versionadded:: 3.7
- *ssl_handshake_timeout* and *start_serving* parameters.
+ Added *ssl_handshake_timeout* and *start_serving* parameters.
- .. versionchanged:: 3.5
+ .. versionchanged:: 3.6
- On Windows with :class:`ProactorEventLoop`, SSL/TLS is now supported.
+ The socket option :py:data:`~socket.TCP_NODELAY` is set by default
+ for all TCP connections.
- .. seealso::
+ .. versionchanged:: 3.5
- The function :func:`start_server` creates a (:class:`StreamReader`,
- :class:`StreamWriter`) pair and calls back a function with this pair.
+ Added support for SSL/TLS in :class:`ProactorEventLoop`.
.. versionchanged:: 3.5.1
- The *host* parameter can now be a sequence of strings.
+ The *host* parameter can be a sequence of strings.
+
+ .. seealso::
+
+ The :func:`start_server` function is a higher-level alternative API
+ that returns a pair of :class:`StreamReader` and :class:`StreamWriter`
+ that can be used in an async/await code.
+
+.. coroutinemethod:: loop.create_unix_server(protocol_factory, path=None, \
+ \*, sock=None, backlog=100, ssl=None, \
+ ssl_handshake_timeout=None, start_serving=True)
-.. coroutinemethod:: AbstractEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, start_serving=True)
+ Similar to :meth:`loop.create_server` but works with the
+ :py:data:`~socket.AF_UNIX` socket family.
- Similar to :meth:`AbstractEventLoop.create_server`, but specific to the
- socket family :py:data:`~socket.AF_UNIX`.
+ *path* is the name of a Unix domain socket, and is required,
+ unless a *sock* argument is provided. Abstract Unix sockets,
+ :class:`str`, :class:`bytes`, and :class:`~pathlib.Path` paths
+ are supported.
- *path* is the name of a UNIX domain socket, and is required unless a *sock*
- parameter is specified. Abstract UNIX sockets, :class:`str`,
- :class:`bytes`, and :class:`~pathlib.Path` paths are supported.
+ See the documentation of the :meth:`loop.create_server` method
+ for information about arguments to this method.
- Availability: UNIX.
+ .. availability:: Unix.
.. versionadded:: 3.7
- The *ssl_handshake_timeout* parameter.
+ The *ssl_handshake_timeout* and *start_serving* parameters.
.. versionchanged:: 3.7
The *path* parameter can now be a :class:`~pathlib.Path` object.
-.. coroutinemethod:: BaseEventLoop.connect_accepted_socket(protocol_factory, sock, \*, ssl=None, ssl_handshake_timeout=None)
+.. coroutinemethod:: loop.connect_accepted_socket(protocol_factory, \
+ sock, \*, ssl=None, ssl_handshake_timeout=None)
- Handle an accepted connection.
+ Wrap an already accepted connection into a transport/protocol pair.
- This is used by servers that accept connections outside of
- asyncio but that use asyncio to handle them.
+ This method can be used by servers that accept connections outside
+ of asyncio but that use asyncio to handle them.
Parameters:
- * *sock* is a preexisting socket object returned from an ``accept``
- call.
+ * *protocol_factory* must be a callable returning a
+ :ref:`protocol ` implementation.
+
+ * *sock* is a preexisting socket object returned from
+ :meth:`socket.accept `.
- * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over the
- accepted connections.
+ * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over
+ the accepted connections.
* *ssl_handshake_timeout* is (for an SSL connection) the time in seconds to
wait for the SSL handshake to complete before aborting the connection.
- ``10.0`` seconds if ``None`` (default).
+ ``60.0`` seconds if ``None`` (default).
- When completed it returns a ``(transport, protocol)`` pair.
+ Returns a ``(transport, protocol)`` pair.
.. versionadded:: 3.7
@@ -543,15 +682,14 @@ Creating listening connections
.. versionadded:: 3.5.3
-File Transferring
------------------
+Transferring files
+^^^^^^^^^^^^^^^^^^
-.. coroutinemethod:: AbstractEventLoop.sendfile(transport, file, \
- offset=0, count=None, \
- *, fallback=True)
+.. coroutinemethod:: loop.sendfile(transport, file, \
+ offset=0, count=None, *, fallback=True)
- Send a *file* to *transport*, return the total number of bytes
- which were sent.
+ Send a *file* over a *transport*. Return the total number of bytes
+ sent.
The method uses high-performance :meth:`os.sendfile` if available.
@@ -559,167 +697,163 @@ File Transferring
*offset* tells from where to start reading the file. If specified,
*count* is the total number of bytes to transmit as opposed to
- sending the file until EOF is reached. File position is updated on
- return or also in case of error in which case :meth:`file.tell()
- ` can be used to figure out the number of bytes
- which were sent.
+ sending the file until EOF is reached. File position is always updated,
+ even when this method raises an error, and
+ :meth:`file.tell() ` can be used to obtain the actual
+ number of bytes sent.
*fallback* set to ``True`` makes asyncio to manually read and send
- the file when the platform does not support the sendfile syscall
+ the file when the platform does not support the sendfile system call
(e.g. Windows or SSL socket on Unix).
Raise :exc:`SendfileNotAvailableError` if the system does not support
- *sendfile* syscall and *fallback* is ``False``.
+ the *sendfile* syscall and *fallback* is ``False``.
.. versionadded:: 3.7
TLS Upgrade
------------
+^^^^^^^^^^^
-.. coroutinemethod:: AbstractEventLoop.start_tls(transport, protocol, sslcontext, \*, server_side=False, server_hostname=None, ssl_handshake_timeout=None)
+.. coroutinemethod:: loop.start_tls(transport, protocol, \
+ sslcontext, \*, server_side=False, \
+ server_hostname=None, ssl_handshake_timeout=None)
- Upgrades an existing connection to TLS.
+ Upgrade an existing transport-based connection to TLS.
- Returns a new transport instance, that the *protocol* must start using
+ Return a new transport instance, that the *protocol* must start using
immediately after the *await*. The *transport* instance passed to
the *start_tls* method should never be used again.
Parameters:
* *transport* and *protocol* instances that methods like
- :meth:`~AbstractEventLoop.create_server` and
- :meth:`~AbstractEventLoop.create_connection` return.
+ :meth:`~loop.create_server` and
+ :meth:`~loop.create_connection` return.
* *sslcontext*: a configured instance of :class:`~ssl.SSLContext`.
* *server_side* pass ``True`` when a server-side connection is being
- upgraded (like the one created by :meth:`~AbstractEventLoop.create_server`).
+ upgraded (like the one created by :meth:`~loop.create_server`).
* *server_hostname*: sets or overrides the host name that the target
server's certificate will be matched against.
- * *ssl_handshake_timeout* is (for an SSL connection) the time in seconds to
- wait for the SSL handshake to complete before aborting the connection.
- ``10.0`` seconds if ``None`` (default).
+ * *ssl_handshake_timeout* is (for a TLS connection) the time in seconds to
+ wait for the TLS handshake to complete before aborting the connection.
+ ``60.0`` seconds if ``None`` (default).
.. versionadded:: 3.7
-Watch file descriptors
-----------------------
-
-On Windows with :class:`SelectorEventLoop`, only socket handles are supported
-(ex: pipe file descriptors are not supported).
+Watching file descriptors
+^^^^^^^^^^^^^^^^^^^^^^^^^
-On Windows with :class:`ProactorEventLoop`, these methods are not supported.
+.. method:: loop.add_reader(fd, callback, \*args)
-.. method:: AbstractEventLoop.add_reader(fd, callback, \*args)
+ Start monitoring the *fd* file descriptor for read availability and
+ invoke *callback* with the specified arguments once *fd* is available for
+ reading.
- Start watching the file descriptor for read availability and then call the
- *callback* with specified arguments.
+.. method:: loop.remove_reader(fd)
- :ref:`Use functools.partial to pass keywords to the callback
- `.
+ Stop monitoring the *fd* file descriptor for read availability.
-.. method:: AbstractEventLoop.remove_reader(fd)
+.. method:: loop.add_writer(fd, callback, \*args)
- Stop watching the file descriptor for read availability.
+ Start monitoring the *fd* file descriptor for write availability and
+ invoke *callback* with the specified arguments once *fd* is available for
+ writing.
-.. method:: AbstractEventLoop.add_writer(fd, callback, \*args)
+ Use :func:`functools.partial` :ref:`to pass keyword arguments
+ ` to *callback*.
- Start watching the file descriptor for write availability and then call the
- *callback* with specified arguments.
+.. method:: loop.remove_writer(fd)
- :ref:`Use functools.partial to pass keywords to the callback
- `.
+ Stop monitoring the *fd* file descriptor for write availability.
-.. method:: AbstractEventLoop.remove_writer(fd)
+See also :ref:`Platform Support ` section
+for some limitations of these methods.
- Stop watching the file descriptor for write availability.
-The :ref:`watch a file descriptor for read events `
-example uses the low-level :meth:`AbstractEventLoop.add_reader` method to register
-the file descriptor of a socket.
+Working with socket objects directly
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In general, protocol implementations that use transport-based APIs
+such as :meth:`loop.create_connection` and :meth:`loop.create_server`
+are faster than implementations that work with sockets directly.
+However, there are some use cases when performance is not critical, and
+working with :class:`~socket.socket` objects directly is more
+convenient.
-Low-level socket operations
----------------------------
+.. coroutinemethod:: loop.sock_recv(sock, nbytes)
-.. coroutinemethod:: AbstractEventLoop.sock_recv(sock, nbytes)
+ Receive up to *nbytes* from *sock*. Asynchronous version of
+ :meth:`socket.recv() `.
- Receive data from the socket. Modeled after blocking
- :meth:`socket.socket.recv` method.
+ Return the received data as a bytes object.
- The return value is a bytes object
- representing the data received. The maximum amount of data to be received
- at once is specified by *nbytes*.
-
- With :class:`SelectorEventLoop` event loop, the socket *sock* must be
- non-blocking.
+ *sock* must be a non-blocking socket.
.. versionchanged:: 3.7
- Even though the method was always documented as a coroutine
- method, before Python 3.7 it returned a :class:`Future`.
- Since Python 3.7, this is an ``async def`` method.
+ Even though this method was always documented as a coroutine
+ method, releases before Python 3.7 returned a :class:`Future`.
+ Since Python 3.7 this is an ``async def`` method.
-.. coroutinemethod:: AbstractEventLoop.sock_recv_into(sock, buf)
+.. coroutinemethod:: loop.sock_recv_into(sock, buf)
- Receive data from the socket. Modeled after blocking
- :meth:`socket.socket.recv_into` method.
+ Receive data from *sock* into the *buf* buffer. Modeled after the blocking
+ :meth:`socket.recv_into() ` method.
- The received data is written into *buf* (a writable buffer).
- The return value is the number of bytes written.
+ Return the number of bytes written to the buffer.
- With :class:`SelectorEventLoop` event loop, the socket *sock* must be
- non-blocking.
+ *sock* must be a non-blocking socket.
.. versionadded:: 3.7
-.. coroutinemethod:: AbstractEventLoop.sock_sendall(sock, data)
+.. coroutinemethod:: loop.sock_sendall(sock, data)
- Send data to the socket. Modeled after blocking
- :meth:`socket.socket.sendall` method.
+ Send *data* to the *sock* socket. Asynchronous version of
+ :meth:`socket.sendall() `.
- The socket must be connected to a remote socket.
- This method continues to send data from *data* until either all data has
- been sent or an error occurs. ``None`` is returned on success. On error,
- an exception is raised, and there is no way to determine how much data, if
- any, was successfully processed by the receiving end of the connection.
+ This method continues to send to the socket until either all data
+ in *data* has been sent or an error occurs. ``None`` is returned
+ on success. On error, an exception is raised. Additionally, there is no way
+ to determine how much data, if any, was successfully processed by the
+ receiving end of the connection.
- With :class:`SelectorEventLoop` event loop, the socket *sock* must be
- non-blocking.
+ *sock* must be a non-blocking socket.
.. versionchanged:: 3.7
Even though the method was always documented as a coroutine
method, before Python 3.7 it returned an :class:`Future`.
Since Python 3.7, this is an ``async def`` method.
-.. coroutinemethod:: AbstractEventLoop.sock_connect(sock, address)
+.. coroutinemethod:: loop.sock_connect(sock, address)
+
+ Connect *sock* to a remote socket at *address*.
- Connect to a remote socket at *address*. Modeled after
- blocking :meth:`socket.socket.connect` method.
+ Asynchronous version of :meth:`socket.connect() `.
- With :class:`SelectorEventLoop` event loop, the socket *sock* must be
- non-blocking.
+ *sock* must be a non-blocking socket.
.. versionchanged:: 3.5.2
``address`` no longer needs to be resolved. ``sock_connect``
will try to check if the *address* is already resolved by calling
:func:`socket.inet_pton`. If not,
- :meth:`AbstractEventLoop.getaddrinfo` will be used to resolve the
+ :meth:`loop.getaddrinfo` will be used to resolve the
*address*.
.. seealso::
- :meth:`AbstractEventLoop.create_connection`
+ :meth:`loop.create_connection`
and :func:`asyncio.open_connection() `.
-.. coroutinemethod:: AbstractEventLoop.sock_accept(sock)
+.. coroutinemethod:: loop.sock_accept(sock)
- Accept a connection. Modeled after blocking
- :meth:`socket.socket.accept`.
+ Accept a connection. Modeled after the blocking
+ :meth:`socket.accept() ` method.
The socket must be bound to an address and listening
for connections. The return value is a pair ``(conn, address)`` where *conn*
@@ -727,7 +861,7 @@ Low-level socket operations
and *address* is the address bound to the socket on the other end of the
connection.
- The socket *sock* must be non-blocking.
+ *sock* must be a non-blocking socket.
.. versionchanged:: 3.7
Even though the method was always documented as a coroutine
@@ -736,51 +870,51 @@ Low-level socket operations
.. seealso::
- :meth:`AbstractEventLoop.create_server` and :func:`start_server`.
+ :meth:`loop.create_server` and :func:`start_server`.
-.. coroutinemethod:: AbstractEventLoop.sock_sendfile(sock, file, \
- offset=0, count=None, \
- *, fallback=True)
+.. coroutinemethod:: loop.sock_sendfile(sock, file, offset=0, count=None, \
+ \*, fallback=True)
- Send a file using high-performance :mod:`os.sendfile` if possible
- and return the total number of bytes which were sent.
+ Send a file using high-performance :mod:`os.sendfile` if possible.
+ Return the total number of bytes sent.
- Asynchronous version of :meth:`socket.socket.sendfile`.
+ Asynchronous version of :meth:`socket.sendfile() `.
- *sock* must be non-blocking :class:`~socket.socket` of
- :const:`socket.SOCK_STREAM` type.
+ *sock* must be a non-blocking :const:`socket.SOCK_STREAM`
+ :class:`~socket.socket`.
- *file* must be a regular file object opened in binary mode.
+ *file* must be a regular file object open in binary mode.
*offset* tells from where to start reading the file. If specified,
*count* is the total number of bytes to transmit as opposed to
- sending the file until EOF is reached. File position is updated on
- return or also in case of error in which case :meth:`file.tell()
- ` can be used to figure out the number of bytes
- which were sent.
+ sending the file until EOF is reached. File position is always updated,
+ even when this method raises an error, and
+ :meth:`file.tell() ` can be used to obtain the actual
+ number of bytes sent.
- *fallback* set to ``True`` makes asyncio to manually read and send
+ *fallback*, when set to ``True``, makes asyncio manually read and send
the file when the platform does not support the sendfile syscall
(e.g. Windows or SSL socket on Unix).
Raise :exc:`SendfileNotAvailableError` if the system does not support
*sendfile* syscall and *fallback* is ``False``.
+ *sock* must be a non-blocking socket.
+
.. versionadded:: 3.7
-Resolve host name
------------------
+DNS
+^^^
-.. coroutinemethod:: AbstractEventLoop.getaddrinfo(host, port, \*, family=0, type=0, proto=0, flags=0)
+.. coroutinemethod:: loop.getaddrinfo(host, port, \*, family=0, \
+ type=0, proto=0, flags=0)
- This method is a :ref:`coroutine `, similar to
- :meth:`socket.getaddrinfo` function but non-blocking.
+ Asynchronous version of :meth:`socket.getaddrinfo`.
-.. coroutinemethod:: AbstractEventLoop.getnameinfo(sockaddr, flags=0)
+.. coroutinemethod:: loop.getnameinfo(sockaddr, flags=0)
- This method is a :ref:`coroutine `, similar to
- :meth:`socket.getnameinfo` function but non-blocking.
+ Asynchronous version of :meth:`socket.getnameinfo`.
.. versionchanged:: 3.7
Both *getaddrinfo* and *getnameinfo* methods were always documented
@@ -789,141 +923,206 @@ Resolve host name
both methods are coroutines.
-Connect pipes
--------------
+Working with pipes
+^^^^^^^^^^^^^^^^^^
-On Windows with :class:`SelectorEventLoop`, these methods are not supported.
-Use :class:`ProactorEventLoop` to support pipes on Windows.
+.. coroutinemethod:: loop.connect_read_pipe(protocol_factory, pipe)
-.. coroutinemethod:: AbstractEventLoop.connect_read_pipe(protocol_factory, pipe)
+ Register the read end of *pipe* in the event loop.
- Register read pipe in eventloop.
+ *protocol_factory* must be a callable returning an
+ :ref:`asyncio protocol ` implementation.
- *protocol_factory* should instantiate object with :class:`Protocol`
- interface. *pipe* is a :term:`file-like object `.
- Return pair ``(transport, protocol)``, where *transport* supports the
- :class:`ReadTransport` interface.
+ *pipe* is a :term:`file-like object `.
+
+ Return pair ``(transport, protocol)``, where *transport* supports
+ the :class:`ReadTransport` interface and *protocol* is an object
+ instantiated by the *protocol_factory*.
With :class:`SelectorEventLoop` event loop, the *pipe* is set to
non-blocking mode.
-.. coroutinemethod:: AbstractEventLoop.connect_write_pipe(protocol_factory, pipe)
+.. coroutinemethod:: loop.connect_write_pipe(protocol_factory, pipe)
+
+ Register the write end of *pipe* in the event loop.
+
+ *protocol_factory* must be a callable returning an
+ :ref:`asyncio protocol ` implementation.
- Register write pipe in eventloop.
+ *pipe* is :term:`file-like object `.
- *protocol_factory* should instantiate object with :class:`BaseProtocol`
- interface. *pipe* is :term:`file-like object `.
Return pair ``(transport, protocol)``, where *transport* supports
- :class:`WriteTransport` interface.
+ :class:`WriteTransport` interface and *protocol* is an object
+ instantiated by the *protocol_factory*.
With :class:`SelectorEventLoop` event loop, the *pipe* is set to
non-blocking mode.
+.. note::
+
+ :class:`SelectorEventLoop` does not support the above methods on
+ Windows. Use :class:`ProactorEventLoop` instead for Windows.
+
.. seealso::
- The :meth:`AbstractEventLoop.subprocess_exec` and
- :meth:`AbstractEventLoop.subprocess_shell` methods.
+ The :meth:`loop.subprocess_exec` and
+ :meth:`loop.subprocess_shell` methods.
-UNIX signals
-------------
+Unix signals
+^^^^^^^^^^^^
-Availability: UNIX only.
+.. method:: loop.add_signal_handler(signum, callback, \*args)
-.. method:: AbstractEventLoop.add_signal_handler(signum, callback, \*args)
+ Set *callback* as the handler for the *signum* signal.
- Add a handler for a signal.
+ The callback will be invoked by *loop*, along with other queued callbacks
+ and runnable coroutines of that event loop. Unlike signal handlers
+ registered using :func:`signal.signal`, a callback registered with this
+ function is allowed to interact with the event loop.
Raise :exc:`ValueError` if the signal number is invalid or uncatchable.
Raise :exc:`RuntimeError` if there is a problem setting up the handler.
- :ref:`Use functools.partial to pass keywords to the callback
- `.
+ Use :func:`functools.partial` :ref:`to pass keyword arguments
+ ` to *callback*.
+
+ Like :func:`signal.signal`, this function must be invoked in the main
+ thread.
-.. method:: AbstractEventLoop.remove_signal_handler(sig)
+.. method:: loop.remove_signal_handler(sig)
- Remove a handler for a signal.
+ Remove the handler for the *sig* signal.
- Return ``True`` if a signal handler was removed, ``False`` if not.
+ Return ``True`` if the signal handler was removed, or ``False`` if
+ no handler was set for the given signal.
+
+ .. availability:: Unix.
.. seealso::
The :mod:`signal` module.
-Executor
---------
-
-Call a function in an :class:`~concurrent.futures.Executor` (pool of threads or
-pool of processes). By default, an event loop uses a thread pool executor
-(:class:`~concurrent.futures.ThreadPoolExecutor`).
+Executing code in thread or process pools
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. method:: AbstractEventLoop.run_in_executor(executor, func, \*args)
+.. awaitablemethod:: loop.run_in_executor(executor, func, \*args)
- Arrange for a *func* to be called in the specified executor.
+ Arrange for *func* to be called in the specified executor.
- The *executor* argument should be an :class:`~concurrent.futures.Executor`
+ The *executor* argument should be an :class:`concurrent.futures.Executor`
instance. The default executor is used if *executor* is ``None``.
- :ref:`Use functools.partial to pass keywords to the *func*
-