diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml
new file mode 100644
index 00000000000000..15a83dd0370e19
--- /dev/null
+++ b/.azure-pipelines/ci.yml
@@ -0,0 +1,162 @@
+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-16.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-16.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'))
+
+ variables:
+ testRunTitle: '$(build.sourceBranchName)-macos'
+ testRunPlatform: macos
+
+ pool:
+ vmImage: xcode9-macos10.13
+
+ 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-16.04
+
+ variables:
+ testRunTitle: '$(build.sourceBranchName)-linux'
+ testRunPlatform: linux
+ openssl_version: 1.1.0j
+
+ 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-16.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-16.04
+
+ variables:
+ testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
+ testRunPlatform: linux-coverage
+ openssl_version: 1.1.0j
+
+ 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:
+ 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..647081689454ac
--- /dev/null
+++ b/.azure-pipelines/macos-steps.yml
@@ -0,0 +1,25 @@
+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 -s -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'
+
+- 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..15e3f0b9ad1bb7
--- /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 -s -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..0bd7921bcbefcc
--- /dev/null
+++ b/.azure-pipelines/pr.yml
@@ -0,0 +1,153 @@
+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-16.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-16.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'))
+
+ variables:
+ testRunTitle: '$(system.pullRequest.TargetBranch)-macos'
+ testRunPlatform: macos
+
+ pool:
+ vmImage: xcode9-macos10.13
+
+ 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-16.04
+
+ variables:
+ testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
+ testRunPlatform: linux
+ openssl_version: 1.1.0j
+
+ 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-16.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-16.04
+
+ variables:
+ testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
+ testRunPlatform: linux-coverage
+ openssl_version: 1.1.0j
+
+ 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:
+ 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
index b7d40787318985..6662732326a3b8 100644
--- a/.github/appveyor.yml
+++ b/.github/appveyor.yml
@@ -7,12 +7,32 @@ branches:
- buildbot-custom
cache:
- externals -> PCbuild\*
+before_build:
+ - ps: |+
+ if ($env:APPVEYOR_RE_BUILD) {
+ echo 'Doing full build due to re-build request.'
+ } elseif (!$env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT) {
+ echo 'Not a PR, doing full build.'
+ } else {
+ git fetch -q origin +refs/heads/$env:APPVEYOR_REPO_BRANCH
+ $mergebase = git merge-base HEAD FETCH_HEAD
+ $changes = git diff --name-only HEAD $mergebase | grep -vE '(\.rst$)|(^Doc)|(^Misc)'
+ If (!$changes) {
+ echo 'Only docs were updated, stopping build process.'
+ Exit-AppveyorBuild
+ } else {
+ echo 'Doing full build due to non-doc changes in these files:'
+ echo $changes
+ }
+ }
+
+
build_script:
-- cmd: PCbuild\build.bat -e
-- cmd: PCbuild\win32\python.exe -m test.pythoninfo
+ - 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
+ - cmd: PCbuild\rt.bat -q -uall -u-cpu -u-largefile -rwW --slowest --timeout=1200 --fail-env-changed -j0
environment:
HOST_PYTHON: C:\Python36\python.exe
image:
-- Visual Studio 2017
+ - Visual Studio 2017
diff --git a/.gitignore b/.gitignore
index 05fb6cba0875a1..58f8bf72f2b9bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -113,3 +113,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..07d26412333c13 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,30 +1,33 @@
language: c
-dist: trusty
-sudo: false
+dist: xenial
group: beta
# 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.0i
- 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 +41,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 +54,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 +142,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/README.rst b/Doc/README.rst
index a29d1f3a708a43..d7bcc5ba7919bb 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::
diff --git a/Doc/bugs.rst b/Doc/bugs.rst
index 109e9eb202d8ea..c449ba2e719203 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).
@@ -89,4 +89,4 @@ 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
.. _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/arg.rst b/Doc/c-api/arg.rst
index e4b48e66bc2d1c..b41130ede416e3 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -151,19 +151,35 @@ which disallows mutable objects such as :class:`bytearray`.
Previously, :exc:`TypeError` was raised when embedded null code points
were encountered in the Python string.
+ .. 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]
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*.
+ .. 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]
Like ``u#``, but the Python object may also be ``None``, in which case the
: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
any conversion. Raises :exc:`TypeError` if the object is not a Unicode
@@ -552,12 +568,13 @@ Building values
``z#`` (:class:`str` or ``None``) [const char \*, int]
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
+ ``u#`` (:class:`str`) [const wchar_t \*, int]
+ 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.
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index 8c2de9691f3e1a..c7c1e3cc745ac4 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -198,7 +198,7 @@ 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
+ 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
@@ -429,7 +429,7 @@ 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)
@@ -470,7 +470,16 @@ 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:: 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'`` (for C-style or Fortran-style ordering).
+ ``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)
@@ -497,6 +506,3 @@ Buffer-related functions
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.
-
-
-
diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst
index b8642d0aba9248..8eb6695e22de18 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::
@@ -104,8 +107,8 @@ 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)
@@ -122,18 +125,21 @@ 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
@@ -142,6 +148,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
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
diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst
index dfe3d436e5f4b7..c55f19970e125d 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)
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index 47dab81891d38f..9558a4a583cba5 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -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..c344c8d71ae32d
--- /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..c46722d782a2fb 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -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
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index b7225faf408ca0..0ced5a5fd00170 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -95,6 +95,10 @@ Dictionary Objects
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)
@@ -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
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 2bc1bd876a2fe2..cd06096ef7bbfb 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -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
@@ -186,34 +190,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 +233,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)
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index f5e0d7ec9c79c3..472cd93ec3f7e1 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:
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index bae49d5ba8125e..a88873bd8f2338 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.
@@ -1018,7 +1022,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
@@ -1379,6 +1383,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
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 4f16b578eb5999..5b1f386fb7e58f 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -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)
@@ -166,7 +166,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 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,7 @@ 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 ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj)
@@ -271,7 +271,7 @@ 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 ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
.. c:function:: double PyLong_AsDouble(PyObject *pylong)
@@ -282,7 +282,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 +292,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..e37dec9949ab68 100644
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -5,11 +5,17 @@
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 the type of keys it supports. This function always
+ succeeds.
.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
@@ -17,35 +23,57 @@ 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)
- Remove the mapping for object *key* from the object *o*. Return ``-1`` on
- failure. This is equivalent to the Python statement ``del o[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)
+
+ 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)
@@ -73,15 +101,3 @@ Mapping Protocol
.. 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..17ec621610b5e3 100644
--- a/Doc/c-api/marshal.rst
+++ b/Doc/c-api/marshal.rst
@@ -40,12 +40,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 +47,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 +57,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 +66,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 +80,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 +89,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..b79b7e49b67e14 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.
@@ -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:
@@ -530,7 +530,7 @@ tracemalloc C API
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.
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 7efab28af724aa..017b656854a8cd 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -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.
+ 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
...........................
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
index 3c7605a67fa226..296b21c132b79a 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -280,3 +280,4 @@ Number Protocol
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..a64ff2e6b58b4c 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,6 +44,11 @@ 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)
@@ -379,8 +388,8 @@ Object Protocol
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
@@ -414,8 +423,8 @@ 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)
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index f1825f079be474..6d22f35e22b1f2 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,9 +20,8 @@ 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)
@@ -120,18 +122,27 @@ 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
+ Return the sequence or iterable *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.
+ a sequence or iterable, raises :exc:`TypeError` with *m* as the message text.
+
+
+.. 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)
@@ -156,12 +167,3 @@ Sequence Protocol
: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/structures.rst b/Doc/c-api/structures.rst
index 797b9045fa8edc..da45da1d3c70db 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -292,7 +292,8 @@ 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`
+ :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*).
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index e4da96c493cd88..994509aa50f2ad 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -205,16 +205,24 @@ accessible to C code. They all work with the current interpreter thread's
.. 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,7 +268,8 @@ 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
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index a66832cfa43492..20bf9f0b0804cd 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -209,7 +209,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..4dfd53fb9f076f 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)
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 3bdf45ad9b61f7..6cbcc273c1f153 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -1167,21 +1167,24 @@ 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.
.. 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
+ 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,26 +1204,29 @@ 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`
+ 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
@@ -1231,28 +1237,36 @@ Sequence Object Structures
.. 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.
+ :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 inplace 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 inplace multiplication
+ via the :c:member:`~PyNumberMethods.nb_inplace_multiply` slot.
.. _buffer-structs:
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 92e22b16a4ef29..39c067d439cc64 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -935,7 +935,7 @@ wchar_t Support
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
@@ -1346,7 +1346,7 @@ These are the "Raw Unicode Escape" codec APIs:
.. 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.
@@ -1515,8 +1515,8 @@ the user settings on the machine running 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
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index cefe9d44bf45a2..317093e95615e3 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -109,6 +109,10 @@ 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)
@@ -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.
diff --git a/Doc/conf.py b/Doc/conf.py
index 19a2f7d67ff831..da8b9d7b2a65bc 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,20 @@
# 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']
+# 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..393a1f03751f82 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-2019 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 6dc86fc5e54cd4..35527c179f3481 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::
@@ -172,46 +416,62 @@ PyDateTime_FromDateAndTime:int:usecond::
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 +480,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 +508,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 +534,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 +563,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 +604,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 +666,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 +689,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 +764,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:
+
+PyEval_EvalFrame:PyObject*::+1:
+PyEval_EvalFrame:PyFrameObject*:f:0:
-PyFile_AsFile:FILE*:::
-PyFile_AsFile:PyFileObject*:p:0:
+PyEval_EvalFrameEx:PyObject*::+1:
+PyEval_EvalFrameEx:PyFrameObject*:f:0:
+PyEval_EvalFrameEx:int:throwflag::
-PyFile_Check:int:::
-PyFile_Check:PyObject*:p:0:
+PyEval_MergeCompilerFlags:int:::
+PyEval_MergeCompilerFlags:PyCompilerFlags*:cf::
-PyFile_FromFile:PyObject*::+1:
-PyFile_FromFile:FILE*:fp::
-PyFile_FromFile:const char*:name::
-PyFile_FromFile:const char*:mode::
-PyFile_FromFile:int(*:close)::
+PyException_GetCause:PyObject*::+1:
+PyException_GetCause:PyObject*:ex:0:
-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_GetContext:PyObject*::+1:
+PyException_GetContext:PyObject*:ex:0:
-PyFile_FromString:PyObject*::+1:
-PyFile_FromString:const char*:name::
-PyFile_FromString:const char*:mode::
+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 +854,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 +905,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 +917,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 +956,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 +984,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 +1003,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 +1037,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 +1058,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 +1116,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 +1166,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 +1221,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 +1229,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 +1243,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 +1294,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 +1392,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 +1410,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 +1421,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 +1429,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 +1476,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 +1511,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 +1526,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 +1587,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 +1608,46 @@ 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:+1:
+PyObject_GenericSetDict:void*:context::
+
PyObject_GetAttr:PyObject*::+1:
PyObject_GetAttr:PyObject*:o:0:
PyObject_GetAttr:PyObject*:attr_name:0:
@@ -997,6 +1656,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 +1674,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 +1761,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 +1856,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 +1905,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 +1918,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 +1941,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 +1976,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 +2002,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 +2020,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::
+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_AsEncodedObject:PyObject*::+1:
-PyString_AsEncodedObject:PyObject*:str:0:
-PyString_AsEncodedObject:const char*:encoding::
-PyString_AsEncodedObject:const char*:errors::
+PyState_AddModule:int:::
+PyState_AddModule:PyObject*:module:+1:
+PyState_AddModule:PyModuleDef*:def::
-PyString_AsString:const char*:::
-PyString_AsString:PyObject*:string:0:
+PyState_FindModule:PyObject*::0:
+PyState_FindModule:PyModuleDef*:def::
-PyString_AsStringAndSize:int:::
-PyString_AsStringAndSize:PyObject*:obj:0:
-PyString_AsStringAndSize:char**:buffer::
-PyString_AsStringAndSize:int*:length::
+PyState_RemoveModule:int:::
+PyState_RemoveModule:PyModuleDef*:def::
-PyString_Check:int:::
-PyString_Check:PyObject*:o:0:
+PyStructSequence_GET_ITEM:PyObject*::0:
+PyStructSequence_GET_ITEM:PyObject*:p:0:
+PyStructSequence_GET_ITEM:Py_ssize_t:pos::
-PyString_Concat:void:::
-PyString_Concat:PyObject**:string:0:??? -- replaces w/ new string or NULL
-PyString_Concat:PyObject*:newpart:0:
+PyStructSequence_GetItem:PyObject*::0:
+PyStructSequence_GetItem:PyObject*:p:0:
+PyStructSequence_GetItem:Py_ssize_t:pos::
-PyString_ConcatAndDel:void:::
-PyString_ConcatAndDel:PyObject**:string:0:??? -- replaces w/ new string or NULL
-PyString_ConcatAndDel:PyObject*:newpart:-1:
+PyStructSequence_InitType:void:::
+PyStructSequence_InitType:PyTypeObject*:type:+1:
+PyStructSequence_InitType:PyStructSequence_Desc*:desc::
-PyString_Format:PyObject*::+1:
-PyString_Format:PyObject*:format:0:
-PyString_Format:PyObject*:args:0:
+PyStructSequence_InitType2:int:::
+PyStructSequence_InitType2:PyTypeObject*:type:+1:
+PyStructSequence_InitType2:PyStructSequence_Desc*:desc::
-PyString_FromString:PyObject*::+1:
-PyString_FromString:const char*:v::
+PyStructSequence_New:PyObject*::+1:
+PyStructSequence_New:PyTypeObject*:type:0:
-PyString_FromStringAndSize:PyObject*::+1:
-PyString_FromStringAndSize:const char*:v::
-PyString_FromStringAndSize:int:len::
+PyStructSequence_NewType:PyTypeObject*::+1:
+PyStructSequence_NewType:PyStructSequence_Desc*:desc::
-PyString_FromFormat:PyObject*::+1:
-PyString_FromFormat:const char*:format::
-PyString_FromFormat::...::
+PyStructSequence_SET_ITEM:void:::
+PyStructSequence_SET_ITEM:PyObject*:p:0:
+PyStructSequence_SET_ITEM:Py_ssize_t*:pos::
+PyStructSequence_SET_ITEM:PyObject*:o:0:
-PyString_FromFormatV:PyObject*::+1:
-PyString_FromFormatV:const char*:format::
-PyString_FromFormatV:va_list:vargs::
-
-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 +2151,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 +2170,182 @@ 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::
+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 +2370,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 +2393,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:Pyssize_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 +2606,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 +2641,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 +2656,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 +2710,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 +2912,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 +2964,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 +2993,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 +3008,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..5dd14b1f7a60b9 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
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index 9fce46ad266962..8efeffb6376e13 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
@@ -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 | |
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index f523a672340876..f1f3471261600e 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:
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/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..50cb74f2b6ca90 100644
--- a/Doc/distutils/packageindex.rst
+++ b/Doc/distutils/packageindex.rst
@@ -156,7 +156,9 @@ 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::
+follows:
+
+.. code-block:: ini
[distutils]
index-servers =
@@ -179,7 +181,9 @@ Each section describing a repository defines three variables:
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::
+listed in the *index-servers* variable:
+
+.. code-block:: ini
[distutils]
index-servers =
@@ -246,4 +250,4 @@ 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..54ed1aebc242d8 100644
--- a/Doc/distutils/setupscript.rst
+++ b/Doc/distutils/setupscript.rst
@@ -524,20 +524,23 @@ following way::
setup(...,
data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
('config', ['cfg/data.cfg']),
- ('/etc/init.d', ['init-script'])]
)
-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
@@ -625,7 +628,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 +685,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/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..7e4fc19db83b2a 100644
--- a/Doc/extending/embedding.rst
+++ b/Doc/extending/embedding.rst
@@ -323,7 +323,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..b788a5575b3f20 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")
@@ -439,7 +441,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 +454,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
@@ -539,8 +545,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
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..d0d2ec1f88207c 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);
}
@@ -1236,7 +357,7 @@ example that simply raises an exception; if this were really all you wanted, the
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;
}
@@ -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
+#. *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
+ :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..ac48637bbee9be
--- /dev/null
+++ b/Doc/extending/newtypes_tutorial.rst
@@ -0,0 +1,896 @@
+.. 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_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*. ::
+
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+
+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);
+ PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+ 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..74e1af6ef24de1 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``.
@@ -277,7 +277,7 @@ 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::
#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/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..31614189a62d2c 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -71,6 +71,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 +376,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)]
@@ -733,7 +738,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 +767,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
===================
@@ -1312,14 +1352,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?
------------------------------------------------------------------------------
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..472351b485ac3c 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -14,8 +14,9 @@ Glossary
``...``
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).
+ 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``.
@@ -313,7 +332,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 +386,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.
+
+ 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::
- See also the :term:`variable annotation` glossary entry.
+ def sum_two_numbers(a: int, b: int) -> int:
+ return a + b
- Annotations are meant to provide a standard way for programmers to
- document types of functions they design. See :pep:`484`, which
- describes this functionality.
+ 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 +436,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 +486,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`.
@@ -603,7 +626,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 +643,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 +659,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
@@ -837,6 +865,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 +1005,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
@@ -974,7 +1019,7 @@ Glossary
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
+ to :term:`named tuple` in that elements can 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
@@ -991,8 +1036,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 +1054,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 +1099,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..695fbb1be192b2 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
@@ -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..f8f2aac70f9b06 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.
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..e391506ce2e49c 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
@@ -976,7 +988,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 +1652,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 +1666,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 +1689,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 +1720,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 +1769,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 +2101,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 +2170,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'|
@@ -2312,7 +2334,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 +2432,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
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..3be6bb380d663b 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -427,25 +427,25 @@ 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
+.. _six: https://pypi.org/project/six
+.. _tox: https://pypi.org/project/tox
+.. _trove classifier: https://pypi.org/classifiers
.. _"What's New": https://docs.python.org/3/whatsnew/index.html
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/unicode.rst b/Doc/howto/unicode.rst
index d4b8f8d2204ab7..5339bf45bf0e80 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.
+Therefore this encoding isn't used very much, and people instead choose other
+encodings that are more efficient and convenient, such as UTF-8.
-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.)
-
-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
@@ -213,6 +156,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 +183,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 +197,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 +239,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 +349,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 +392,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 +488,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 +590,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 +620,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 +642,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 +719,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 +754,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..fb2c7b2a430e64
--- /dev/null
+++ b/Doc/includes/custom.c
@@ -0,0 +1,39 @@
+#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);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c
new file mode 100644
index 00000000000000..51ab4b80d68098
--- /dev/null
+++ b/Doc/includes/custom2.c
@@ -0,0 +1,132 @@
+#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);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c
new file mode 100644
index 00000000000000..09e87355b91afa
--- /dev/null
+++ b/Doc/includes/custom3.c
@@ -0,0 +1,183 @@
+#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);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c
new file mode 100644
index 00000000000000..0994d8fda0e51f
--- /dev/null
+++ b/Doc/includes/custom4.c
@@ -0,0 +1,197 @@
+#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);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
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..9caf1fdb20104a 100644
--- a/Doc/includes/run-func.c
+++ b/Doc/includes/run-func.c
@@ -3,7 +3,7 @@
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/sublist.c b/Doc/includes/sublist.c
new file mode 100644
index 00000000000000..376dddfac09c68
--- /dev/null
+++ b/Doc/includes/sublist.c
@@ -0,0 +1,63 @@
+#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);
+ PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+ 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..f6a8cd6833a9ad 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.)
@@ -582,10 +584,10 @@ 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..8af828bb8a105f 100644
--- a/Doc/installing/index.rst
+++ b/Doc/installing/index.rst
@@ -44,11 +44,11 @@ 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,
diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst
index deb5e10f6ef7e9..fa4b0a9645531c 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
diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst
index 67cb70944f4da1..acffabf24bad5f 100644
--- a/Doc/library/_thread.rst
+++ b/Doc/library/_thread.rst
@@ -101,7 +101,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..cef197f3055581 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
@@ -844,6 +844,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 +878,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 +892,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 +904,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 +987,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 +1545,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 +1583,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``.
* help_ - help for sub-parser group in help output, by default ``None``
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index b7f610ba8b2a5f..3c73f748acbe36 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)
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..b7288036192979 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 block 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..d59cf055b61417 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -1,103 +1,163 @@
.. 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. If there is no current event loop set
+ in the current OS thread and :func:`set_event_loop` has not yet
+ been called, asyncio will create a new event loop and set it as the
+ current one.
-.. method:: AbstractEventLoop.run_forever()
+ 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.
- 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.
+ Consider also using the :func:`asyncio.run` function instead of using
+ lower level functions to manually create and close an event loop.
- .. versionchanged:: 3.5.1
+.. function:: set_event_loop(loop)
-.. method:: AbstractEventLoop.run_until_complete(future)
+ Set *loop* as a current event loop for the current OS thread.
- Run until the :class:`Future` is done.
+.. function:: new_event_loop()
- If the argument is a :ref:`coroutine object `, it is wrapped by
- :func:`ensure_future`.
+ Create a new event loop object.
- Return the Future's result, or raise its exception.
+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 `.
-.. method:: AbstractEventLoop.is_running()
- Returns running status of event loop.
+.. rubric:: Contents
-.. method:: AbstractEventLoop.stop()
+This documentation page contains the following sections:
- Stop running the event loop.
+* The `Event Loop Methods`_ section is the reference documentation of
+ the event loop APIs;
- This causes :meth:`run_forever` to exit at the next suitable
- opportunity (see there for more details).
+* 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`;
- .. versionchanged:: 3.5.1
+* 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 +168,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.
-.. method:: AbstractEventLoop.time()
+ .. 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.
- Return the current time, as a :class:`float` value, according to the
- event loop's internal clock.
+.. method:: loop.time()
-.. seealso::
+ Return the current time, as a :class:`float` value, according to
+ the event loop's internal monotonic clock.
- The :func:`asyncio.sleep` function.
+.. note::
+ Timeouts (relative *delay* or absolute *when*) should not
+ exceed one day.
-Futures
--------
+.. seealso::
-.. method:: AbstractEventLoop.create_future()
+ The :func:`asyncio.sleep` function.
- Create an :class:`asyncio.Future` object attached to the 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).
+Creating Futures and Tasks
+^^^^^^^^^^^^^^^^^^^^^^^^^^
- .. versionadded:: 3.5.2
+.. method:: loop.create_future()
+ Create an :class:`asyncio.Future` object attached to the event loop.
-Tasks
------
+ 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).
-.. method:: AbstractEventLoop.create_task(coro)
+ .. versionadded:: 3.5.2
- Schedule the execution of a :ref:`coroutine object `: wrap it in
- a future. Return a :class:`Task` object.
+.. method:: loop.create_task(coro)
- 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.
-
- .. 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``.
+ The created transport is an implementation-dependent bidirectional
+ stream.
- 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 +398,51 @@ 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)
+ Create a datagram connection.
- 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.
+ 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).
- This method will try to establish the connection in the background.
- When successful, the it returns a ``(transport, protocol)`` pair.
+ The socket type will be :py:data:`~socket.SOCK_DGRAM`.
- Options changing how the connection is created:
+ *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*
@@ -370,14 +458,14 @@ Creating connections
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
+ ``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
- 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 +476,35 @@ 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)
+.. coroutinemethod:: loop.create_unix_connection(protocol_factory, \
+ path=None, \*, ssl=None, sock=None, \
+ server_hostname=None, ssl_handshake_timeout=None)
- 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.
+ Create a Unix connection.
- This method will try to establish the connection in the background.
- When successful, the it returns a ``(transport, protocol)`` pair.
+ The socket family will be :py:data:`~socket.AF_UNIX`; socket
+ type will be :py:data:`~socket.SOCK_STREAM`.
+
+ A tuple of ``(transport, protocol)`` is returned on success.
- *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.
+ *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 :meth:`AbstractEventLoop.create_connection` method for parameters.
+ See the documentation of the :meth:`loop.create_connection` method
+ for information about arguments to this method.
- Availability: UNIX.
+ .. availability:: Unix.
.. versionadded:: 3.7
@@ -418,59 +512,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 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).
+ * The *host* parameter can be set to several types which determine where
+ the server would be listening:
+
+ - 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 +587,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::
-.. coroutinemethod:: AbstractEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, start_serving=True)
+ 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.
- 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*
- parameter is specified. Abstract UNIX sockets, :class:`str`,
- :class:`bytes`, and :class:`~pathlib.Path` paths are supported.
+.. coroutinemethod:: loop.create_unix_server(protocol_factory, path=None, \
+ \*, sock=None, backlog=100, ssl=None, \
+ ssl_handshake_timeout=None, start_serving=True)
- Availability: UNIX.
+ Similar to :meth:`loop.create_server` but works with the
+ :py:data:`~socket.AF_UNIX` socket family.
+
+ *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.
+
+ See the documentation of the :meth:`loop.create_server` method
+ for information about arguments to this method.
+
+ .. 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 +666,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 +681,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 +845,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 +854,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 +907,206 @@ Resolve host name
both methods are coroutines.
-Connect pipes
--------------
+Working with pipes
+^^^^^^^^^^^^^^^^^^
+
+.. coroutinemethod:: loop.connect_read_pipe(protocol_factory, pipe)
-On Windows with :class:`SelectorEventLoop`, these methods are not supported.
-Use :class:`ProactorEventLoop` to support pipes on Windows.
+ Register the read end of *pipe* in the event loop.
-.. coroutinemethod:: AbstractEventLoop.connect_read_pipe(protocol_factory, pipe)
+ *protocol_factory* must be a callable returning an
+ :ref:`asyncio protocol ` implementation.
- Register read pipe in eventloop.
+ *pipe* is a :term:`file-like object `.
- *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.
+ 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 write pipe in eventloop.
+ Register the write end of *pipe* in the event loop.
+
+ *protocol_factory* must be a callable returning an
+ :ref:`asyncio protocol ` implementation.
+
+ *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:: loop.remove_signal_handler(sig)
-.. method:: AbstractEventLoop.remove_signal_handler(sig)
+ Remove the handler for the *sig* signal.
- Remove a handler for a signal.
+ Return ``True`` if the signal handler was removed, or ``False`` if
+ no handler was set for the given signal.
- Return ``True`` if a signal handler was removed, ``False`` if not.
+ .. availability:: Unix.
.. seealso::
The :mod:`signal` module.
-Executor
---------
+Executing code in thread or process pools
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-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`).
+.. awaitablemethod:: loop.run_in_executor(executor, func, \*args)
-.. method:: AbstractEventLoop.run_in_executor(executor, func, \*args)
+ Arrange for *func* to be called in the specified executor.
- Arrange for a *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*
- `.
+ Example::
+
+ import asyncio
+ import concurrent.futures
+
+ def blocking_io():
+ # File operations (such as logging) can block the
+ # event loop: run them in a thread pool.
+ with open('/dev/urandom', 'rb') as f:
+ return f.read(100)
+
+ def cpu_bound():
+ # CPU-bound operations will block the event loop:
+ # in general it is preferable to run them in a
+ # process pool.
+ return sum(i * i for i in range(10 ** 7))
+
+ async def main():
+ loop = asyncio.get_running_loop()
+
+ ## Options:
+
+ # 1. Run in the default loop's executor:
+ result = await loop.run_in_executor(
+ None, blocking_io)
+ print('default thread pool', result)
+
+ # 2. Run in a custom thread pool:
+ with concurrent.futures.ThreadPoolExecutor() as pool:
+ result = await loop.run_in_executor(
+ pool, blocking_io)
+ print('custom thread pool', result)
+
+ # 3. Run in a custom process pool:
+ with concurrent.futures.ProcessPoolExecutor() as pool:
+ result = await loop.run_in_executor(
+ pool, cpu_bound)
+ print('custom process pool', result)
+
+ asyncio.run(main())
This method returns a :class:`asyncio.Future` object.
+ Use :func:`functools.partial` :ref:`to pass keyword arguments
+ ` to *func*.
+
.. versionchanged:: 3.5.3
- :meth:`BaseEventLoop.run_in_executor` no longer configures the
+ :meth:`loop.run_in_executor` no longer configures the
``max_workers`` of the thread pool executor it creates, instead
leaving it up to the thread pool executor
(:class:`~concurrent.futures.ThreadPoolExecutor`) to set the
default.
-.. method:: AbstractEventLoop.set_default_executor(executor)
+.. method:: loop.set_default_executor(executor)
+
+ Set *executor* as the default executor used by :meth:`run_in_executor`.
+ *executor* should be an instance of
+ :class:`~concurrent.futures.ThreadPoolExecutor`.
+
+ .. deprecated:: 3.7
+ Using an executor that is not an instance of
+ :class:`~concurrent.futures.ThreadPoolExecutor` is deprecated and
+ will trigger an error in Python 3.9.
- Set the default executor used by :meth:`run_in_executor`.
+ *executor* must be an instance of
+ :class:`concurrent.futures.ThreadPoolExecutor`.
Error Handling API
-------------------
+^^^^^^^^^^^^^^^^^^
Allows customizing how exceptions are handled in the event loop.
-.. method:: AbstractEventLoop.set_exception_handler(handler)
+.. method:: loop.set_exception_handler(handler)
Set *handler* as the new event loop exception handler.
If *handler* is ``None``, the default exception handler will
- be set.
+ be set. Otherwise, *handler* must be a callable with the signature
+ matching ``(loop, context)``, where ``loop``
+ is a reference to the active event loop, and ``context``
+ is a ``dict`` object containing the details of the exception
+ (see :meth:`call_exception_handler` documentation for details
+ about context).
- If *handler* is a callable object, it should have a
- matching signature to ``(loop, context)``, where ``loop``
- will be a reference to the active event loop, ``context``
- will be a ``dict`` object (see :meth:`call_exception_handler`
- documentation for details about context).
+.. method:: loop.get_exception_handler()
-.. method:: AbstractEventLoop.get_exception_handler()
-
- Return the exception handler, or ``None`` if the default one
- is in use.
+ Return the current exception handler, or ``None`` if no custom
+ exception handler was set.
.. versionadded:: 3.5.2
-.. method:: AbstractEventLoop.default_exception_handler(context)
+.. method:: loop.default_exception_handler(context)
Default exception handler.
This is called when an exception occurs and no exception
- handler is set, and can be called by a custom exception
- handler that wants to defer to the default behavior.
+ handler is set. This can be called by a custom exception
+ handler that wants to defer to the default handler behavior.
*context* parameter has the same meaning as in
:meth:`call_exception_handler`.
-.. method:: AbstractEventLoop.call_exception_handler(context)
+.. method:: loop.call_exception_handler(context)
Call the current event loop exception handler.
*context* is a ``dict`` object containing the following keys
- (new keys may be introduced later):
+ (new keys may be introduced in future Python versions):
* 'message': Error message;
* 'exception' (optional): Exception object;
@@ -935,14 +1118,14 @@ Allows customizing how exceptions are handled in the event loop.
.. note::
- Note: this method should not be overloaded in subclassed
- event loops. For any custom exception handling, use
- :meth:`set_exception_handler()` method.
+ This method should not be overloaded in subclassed
+ event loops. For custom exception handling, use
+ the :meth:`set_exception_handler()` method.
-Debug mode
-----------
+Enabling debug mode
+^^^^^^^^^^^^^^^^^^^
-.. method:: AbstractEventLoop.get_debug()
+.. method:: loop.get_debug()
Get the debug mode (:class:`bool`) of the event loop.
@@ -950,29 +1133,173 @@ Debug mode
:envvar:`PYTHONASYNCIODEBUG` is set to a non-empty string, ``False``
otherwise.
- .. versionadded:: 3.4.2
-
-.. method:: AbstractEventLoop.set_debug(enabled: bool)
+.. method:: loop.set_debug(enabled: bool)
Set the debug mode of the event loop.
- .. versionadded:: 3.4.2
+ .. versionchanged:: 3.7
+
+ The new ``-X dev`` command line option can now also be used
+ to enable the debug mode.
.. seealso::
The :ref:`debug mode of asyncio `.
-Server
-------
-.. class:: Server
+Running Subprocesses
+^^^^^^^^^^^^^^^^^^^^
+
+Methods described in this subsections are low-level. In regular
+async/await code consider using the high-level
+:func:`asyncio.create_subprocess_shell` and
+:func:`asyncio.create_subprocess_exec` convenience functions instead.
+
+.. note::
+
+ The default asyncio event loop on **Windows** does not support
+ subprocesses. See :ref:`Subprocess Support on Windows
+ ` for details.
+
+.. coroutinemethod:: loop.subprocess_exec(protocol_factory, \*args, \
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
+ stderr=subprocess.PIPE, \*\*kwargs)
+
+ Create a subprocess from one or more string arguments specified by
+ *args*.
+
+ *args* must be a list of strings represented by:
+
+ * :class:`str`;
+ * or :class:`bytes`, encoded to the
+ :ref:`filesystem encoding `.
+
+ The first string specifies the program executable,
+ and the remaining strings specify the arguments. Together, string
+ arguments form the ``argv`` of the program.
+
+ This is similar to the standard library :class:`subprocess.Popen`
+ class called with ``shell=False`` and the list of strings passed as
+ the first argument; however, where :class:`~subprocess.Popen` takes
+ a single argument which is list of strings, *subprocess_exec*
+ takes multiple string arguments.
+
+ The *protocol_factory* must be a callable returning a subclass of the
+ :class:`asyncio.SubprocessProtocol` class.
+
+ Other parameters:
+
+ * *stdin*: either a file-like object representing a pipe to be
+ connected to the subprocess's standard input stream using
+ :meth:`~loop.connect_write_pipe`, or the
+ :const:`subprocess.PIPE` constant (default). By default a new
+ pipe will be created and connected.
+
+ * *stdout*: either a file-like object representing the pipe to be
+ connected to the subprocess's standard output stream using
+ :meth:`~loop.connect_read_pipe`, or the
+ :const:`subprocess.PIPE` constant (default). By default a new pipe
+ will be created and connected.
+
+ * *stderr*: either a file-like object representing the pipe to be
+ connected to the subprocess's standard error stream using
+ :meth:`~loop.connect_read_pipe`, or one of
+ :const:`subprocess.PIPE` (default) or :const:`subprocess.STDOUT`
+ constants.
+
+ By default a new pipe will be created and connected. When
+ :const:`subprocess.STDOUT` is specified, the subprocess' standard
+ error stream will be connected to the same pipe as the standard
+ output stream.
+
+ * All other keyword arguments are passed to :class:`subprocess.Popen`
+ without interpretation, except for *bufsize*, *universal_newlines*
+ and *shell*, which should not be specified at all.
+
+ See the constructor of the :class:`subprocess.Popen` class
+ for documentation on other arguments.
+
+ Returns a pair of ``(transport, protocol)``, where *transport*
+ conforms to the :class:`asyncio.SubprocessTransport` base class and
+ *protocol* is an object instantiated by the *protocol_factory*.
+
+.. coroutinemethod:: loop.subprocess_shell(protocol_factory, cmd, \*, \
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
+ stderr=subprocess.PIPE, \*\*kwargs)
+
+ Create a subprocess from *cmd*, which can be a :class:`str` or a
+ :class:`bytes` string encoded to the
+ :ref:`filesystem encoding `,
+ using the platform's "shell" syntax.
+
+ This is similar to the standard library :class:`subprocess.Popen`
+ class called with ``shell=True``.
+
+ The *protocol_factory* must be a callable returning a subclass of the
+ :class:`SubprocessProtocol` class.
+
+ See :meth:`~loop.subprocess_exec` for more details about
+ the remaining arguments.
+
+ Returns a pair of ``(transport, protocol)``, where *transport*
+ conforms to the :class:`SubprocessTransport` base class and
+ *protocol* is an object instantiated by the *protocol_factory*.
+
+.. note::
+ It is the application's responsibility to ensure that all whitespace
+ and special characters are quoted appropriately to avoid `shell injection
+ `_
+ vulnerabilities. The :func:`shlex.quote` function can be used to
+ properly escape whitespace and special characters in strings that
+ are going to be used to construct shell commands.
+
+
+Callback Handles
+================
+
+.. class:: Handle
+
+ A callback wrapper object returned by :meth:`loop.call_soon`,
+ :meth:`loop.call_soon_threadsafe`.
+
+ .. method:: cancel()
+
+ Cancel the callback. If the callback has already been canceled
+ or executed, this method has no effect.
+
+ .. method:: cancelled()
+
+ Return ``True`` if the callback was cancelled.
+
+ .. versionadded:: 3.7
+
+.. class:: TimerHandle
+
+ A callback wrapper object returned by :meth:`loop.call_later`,
+ and :meth:`loop.call_at`.
- Server listening on sockets.
+ This class is a subclass of :class:`Handle`.
- Object created by :meth:`AbstractEventLoop.create_server`,
- :meth:`AbstractEventLoop.create_unix_server`, :func:`start_server`,
- and :func:`start_unix_server` functions. Don't instantiate the class
- directly.
+ .. method:: when()
+
+ Return a scheduled callback time as :class:`float` seconds.
+
+ The time is an absolute timestamp, using the same time
+ reference as :meth:`loop.time`.
+
+ .. versionadded:: 3.7
+
+
+Server Objects
+==============
+
+Server objects are created by :meth:`loop.create_server`,
+:meth:`loop.create_unix_server`, :func:`start_server`,
+and :func:`start_unix_server` functions.
+
+Do not instantiate the class directly.
+
+.. class:: Server
*Server* objects are asynchronous context managers. When used in an
``async with`` statement, it's guaranteed that the Server object is
@@ -995,15 +1322,15 @@ Server
Stop serving: close listening sockets and set the :attr:`sockets`
attribute to ``None``.
- The sockets that represent existing incoming client connections are left
- open.
+ The sockets that represent existing incoming client connections
+ are left open.
The server is closed asynchronously, use the :meth:`wait_closed`
coroutine to wait until the server is closed.
.. method:: get_loop()
- Gives the event loop associated with the server object.
+ Return the event loop associated with the server object.
.. versionadded:: 3.7
@@ -1014,12 +1341,12 @@ Server
This method is idempotent, so it can be called when
the server is already being serving.
- The new *start_serving* keyword-only parameter to
- :meth:`AbstractEventLoop.create_server` and
- :meth:`asyncio.start_server` allows to create a Server object
- that is not accepting connections right away. In which case
- this method, or :meth:`Server.serve_forever` can be used
- to make the Server object to start accepting connections.
+ The *start_serving* keyword-only parameter to
+ :meth:`loop.create_server` and
+ :meth:`asyncio.start_server` allows creating a Server object
+ that is not accepting connections initially. In this case
+ ``Server.start_serving()``, or :meth:`Server.serve_forever` can be used
+ to make the Server start accepting connections.
.. versionadded:: 3.7
@@ -1043,7 +1370,7 @@ Server
async def main(host, port):
srv = await asyncio.start_server(
client_connected, host, port)
- await loop.serve_forever()
+ await srv.serve_forever()
asyncio.run(main('127.0.0.1', 0))
@@ -1061,63 +1388,99 @@ Server
.. attribute:: sockets
- List of :class:`socket.socket` objects the server is listening to, or
- ``None`` if the server is closed.
+ List of :class:`socket.socket` objects the server is listening on,
+ or ``None`` if the server is closed.
.. versionchanged:: 3.7
- Prior to Python 3.7 ``Server.sockets`` used to return the
- internal list of server's sockets directly. In 3.7 a copy
+ Prior to Python 3.7 ``Server.sockets`` used to return an
+ internal list of server sockets directly. In 3.7 a copy
of that list is returned.
-Handle
-------
+.. _asyncio-event-loops:
-.. class:: Handle
+Event Loop Implementations
+==========================
- A callback wrapper object returned by :func:`AbstractEventLoop.call_soon`,
- :func:`AbstractEventLoop.call_soon_threadsafe`, :func:`AbstractEventLoop.call_later`,
- and :func:`AbstractEventLoop.call_at`.
+asyncio ships with two different event loop implementations:
+:class:`SelectorEventLoop` and :class:`ProactorEventLoop`.
- .. method:: cancel()
+By default asyncio is configured to use :class:`SelectorEventLoop`
+on all platforms.
- Cancel the call. If the callback is already canceled or executed,
- this method has no effect.
- .. method:: cancelled()
+.. class:: SelectorEventLoop
- Return ``True`` if the call was cancelled.
+ An event loop based on the :mod:`selectors` module.
- .. versionadded:: 3.7
+ Uses the most efficient *selector* available for the given
+ platform. It is also possible to manually configure the
+ exact selector implementation to be used::
+
+ import asyncio
+ import selectors
+
+ selector = selectors.SelectSelector()
+ loop = asyncio.SelectorEventLoop(selector)
+ asyncio.set_event_loop(loop)
+
+
+ .. availability:: Unix, Windows.
+
+
+.. class:: ProactorEventLoop
+
+ An event loop for Windows that uses "I/O Completion Ports" (IOCP).
+
+ .. availability:: Windows.
+
+ An example how to use :class:`ProactorEventLoop` on Windows::
+
+ import asyncio
+ import sys
+
+ if sys.platform == 'win32':
+ loop = asyncio.ProactorEventLoop()
+ asyncio.set_event_loop(loop)
+
+ .. seealso::
+ `MSDN documentation on I/O Completion Ports
+ `_.
-SendfileNotAvailableError
--------------------------
+.. class:: AbstractEventLoop
+
+ Abstract base class for asyncio-compliant event loops.
-.. exception:: SendfileNotAvailableError
+ The :ref:`Event Loop Methods ` section lists all
+ methods that an alternative implementation of ``AbstractEventLoop``
+ should have defined.
- Sendfile syscall is not available, subclass of :exc:`RuntimeError`.
- Raised if the OS does not support senfile syscall for
- given socket or file type.
+Examples
+========
+Note that all examples in this section **purposefully** show how
+to use the low-level event loop APIs, such as :meth:`loop.run_forever`
+and :meth:`loop.call_soon`. Modern asyncio applications rarely
+need to be written this way; consider using the high-level functions
+like :func:`asyncio.run`.
-Event loop examples
--------------------
-.. _asyncio-hello-world-callback:
+.. _asyncio_example_lowlevel_helloworld:
Hello World with call_soon()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Example using the :meth:`AbstractEventLoop.call_soon` method to schedule a
-callback. The callback displays ``"Hello World"`` and then stops the event
-loop::
+An example using the :meth:`loop.call_soon` method to schedule a
+callback. The callback displays ``"Hello World"`` and then stops the
+event loop::
import asyncio
def hello_world(loop):
+ """A callback to print 'Hello World' and stop the event loop"""
print('Hello World')
loop.stop()
@@ -1127,23 +1490,25 @@ loop::
loop.call_soon(hello_world, loop)
# Blocking call interrupted by loop.stop()
- loop.run_forever()
- loop.close()
+ try:
+ loop.run_forever()
+ finally:
+ loop.close()
.. seealso::
- The :ref:`Hello World coroutine ` example
- uses a :ref:`coroutine `.
+ A similar :ref:`Hello World `
+ example created with a coroutine and the :func:`run` function.
-.. _asyncio-date-callback:
+.. _asyncio_example_call_later:
Display the current date with call_later()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Example of callback displaying the current date every second. The callback uses
-the :meth:`AbstractEventLoop.call_later` method to reschedule itself during 5
-seconds, and then stops the event loop::
+An example of a callback displaying the current date every second. The
+callback uses the :meth:`loop.call_later` method to reschedule itself
+after 5 seconds, and then stops the event loop::
import asyncio
import datetime
@@ -1162,36 +1527,40 @@ seconds, and then stops the event loop::
loop.call_soon(display_date, end_time, loop)
# Blocking call interrupted by loop.stop()
- loop.run_forever()
- loop.close()
+ try:
+ loop.run_forever()
+ finally:
+ loop.close()
.. seealso::
- The :ref:`coroutine displaying the current date
- ` example uses a :ref:`coroutine
- `.
+ A similar :ref:`current date ` example
+ created with a coroutine and the :func:`run` function.
-.. _asyncio-watch-read-event:
+.. _asyncio_example_watch_fd:
Watch a file descriptor for read events
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Wait until a file descriptor received some data using the
-:meth:`AbstractEventLoop.add_reader` method and then close the event loop::
+:meth:`loop.add_reader` method and then close the event loop::
import asyncio
from socket import socketpair
# Create a pair of connected file descriptors
rsock, wsock = socketpair()
+
loop = asyncio.get_event_loop()
def reader():
data = rsock.recv(100)
print("Received:", data.decode())
+
# We are done: unregister the file descriptor
loop.remove_reader(rsock)
+
# Stop the event loop
loop.stop()
@@ -1201,30 +1570,35 @@ Wait until a file descriptor received some data using the
# Simulate the reception of data from the network
loop.call_soon(wsock.send, 'abc'.encode())
- # Run the event loop
- loop.run_forever()
-
- # We are done, close sockets and the event loop
- rsock.close()
- wsock.close()
- loop.close()
+ try:
+ # Run the event loop
+ loop.run_forever()
+ finally:
+ # We are done. Close sockets and the event loop.
+ rsock.close()
+ wsock.close()
+ loop.close()
.. seealso::
- The :ref:`register an open socket to wait for data using a protocol
- ` example uses a low-level protocol created by the
- :meth:`AbstractEventLoop.create_connection` method.
+ * A similar :ref:`example `
+ using transports, protocols, and the
+ :meth:`loop.create_connection` method.
- The :ref:`register an open socket to wait for data using streams
- ` example uses high-level streams
- created by the :func:`open_connection` function in a coroutine.
+ * Another similar :ref:`example `
+ using the high-level :func:`asyncio.open_connection` function
+ and streams.
+.. _asyncio_example_unix_signals:
+
Set signal handlers for SIGINT and SIGTERM
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM` using
-the :meth:`AbstractEventLoop.add_signal_handler` method::
+(This ``signals`` example only works on Unix.)
+
+Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM`
+using the :meth:`loop.add_signal_handler` method::
import asyncio
import functools
@@ -1235,16 +1609,17 @@ the :meth:`AbstractEventLoop.add_signal_handler` method::
print("got signal %s: exit" % signame)
loop.stop()
- loop = asyncio.get_event_loop()
- for signame in ('SIGINT', 'SIGTERM'):
- loop.add_signal_handler(getattr(signal, signame),
- functools.partial(ask_exit, signame))
+ async def main():
+ loop = asyncio.get_running_loop()
- print("Event loop running forever, press Ctrl+C to interrupt.")
- print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())
- try:
- loop.run_forever()
- finally:
- loop.close()
+ for signame in {'SIGINT', 'SIGTERM'}:
+ loop.add_signal_handler(
+ getattr(signal, signame),
+ functools.partial(ask_exit, signame))
+
+ await asyncio.sleep(3600)
+
+ print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
+ print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")
-This example only works on UNIX.
+ asyncio.run(main())
diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst
deleted file mode 100644
index 3051fde5b93baf..00000000000000
--- a/Doc/library/asyncio-eventloops.rst
+++ /dev/null
@@ -1,241 +0,0 @@
-.. currentmodule:: asyncio
-
-Event loops
-===========
-
-**Source code:** :source:`Lib/asyncio/events.py`
-
-Event loop functions
---------------------
-
-The following functions are convenient shortcuts to accessing the methods of the
-global policy. Note that this provides access to the default policy, unless an
-alternative policy was set by calling :func:`set_event_loop_policy` earlier in
-the execution of the process.
-
-.. function:: get_event_loop()
-
- Equivalent to calling ``get_event_loop_policy().get_event_loop()``.
-
-.. function:: set_event_loop(loop)
-
- Equivalent to calling ``get_event_loop_policy().set_event_loop(loop)``.
-
-.. function:: new_event_loop()
-
- Equivalent to calling ``get_event_loop_policy().new_event_loop()``.
-
-.. function:: get_running_loop()
-
- Return the running event loop in the current OS thread. If there
- is no running event loop a :exc:`RuntimeError` is raised.
-
- .. versionadded:: 3.7
-
-
-.. _asyncio-event-loops:
-
-Available event loops
----------------------
-
-asyncio currently provides two implementations of event loops:
-:class:`SelectorEventLoop` and :class:`ProactorEventLoop`.
-
-.. class:: SelectorEventLoop
-
- Event loop based on the :mod:`selectors` module. Subclass of
- :class:`AbstractEventLoop`.
-
- Use the most efficient selector available on the platform.
-
- On Windows, only sockets are supported (ex: pipes are not supported):
- see the `MSDN documentation of select
- `_.
-
-.. class:: ProactorEventLoop
-
- Proactor event loop for Windows using "I/O Completion Ports" aka IOCP.
- Subclass of :class:`AbstractEventLoop`.
-
- Availability: Windows.
-
- .. seealso::
-
- `MSDN documentation on I/O Completion Ports
- `_.
-
-Example to use a :class:`ProactorEventLoop` on Windows::
-
- import asyncio, sys
-
- if sys.platform == 'win32':
- loop = asyncio.ProactorEventLoop()
- asyncio.set_event_loop(loop)
-
-.. _asyncio-platform-support:
-
-Platform support
-----------------
-
-The :mod:`asyncio` module has been designed to be portable, but each platform
-still has subtle differences and may not support all :mod:`asyncio` features.
-
-Windows
-^^^^^^^
-
-Common limits of Windows event loops:
-
-- :meth:`~AbstractEventLoop.create_unix_connection` and
- :meth:`~AbstractEventLoop.create_unix_server` are not supported: the socket
- family :data:`socket.AF_UNIX` is specific to UNIX
-- :meth:`~AbstractEventLoop.add_signal_handler` and
- :meth:`~AbstractEventLoop.remove_signal_handler` are not supported
-- :meth:`EventLoopPolicy.set_child_watcher` is not supported.
- :class:`ProactorEventLoop` supports subprocesses. It has only one
- implementation to watch child processes, there is no need to configure it.
-
-:class:`SelectorEventLoop` specific limits:
-
-- :class:`~selectors.SelectSelector` is used which only supports sockets
- and is limited to 512 sockets.
-- :meth:`~AbstractEventLoop.add_reader` and :meth:`~AbstractEventLoop.add_writer` only
- accept file descriptors of sockets
-- Pipes are not supported
- (ex: :meth:`~AbstractEventLoop.connect_read_pipe`,
- :meth:`~AbstractEventLoop.connect_write_pipe`)
-- :ref:`Subprocesses ` are not supported
- (ex: :meth:`~AbstractEventLoop.subprocess_exec`,
- :meth:`~AbstractEventLoop.subprocess_shell`)
-
-:class:`ProactorEventLoop` specific limits:
-
-- :meth:`~AbstractEventLoop.create_datagram_endpoint` (UDP) is not supported
-- :meth:`~AbstractEventLoop.add_reader` and :meth:`~AbstractEventLoop.add_writer` are
- not supported
-
-The resolution of the monotonic clock on Windows is usually around 15.6 msec.
-The best resolution is 0.5 msec. The resolution depends on the hardware
-(availability of `HPET
-`_) and on the Windows
-configuration. See :ref:`asyncio delayed calls `.
-
-.. versionchanged:: 3.5
-
- :class:`ProactorEventLoop` now supports SSL.
-
-
-Mac OS X
-^^^^^^^^
-
-Character devices like PTY are only well supported since Mavericks (Mac OS
-10.9). They are not supported at all on Mac OS 10.5 and older.
-
-On Mac OS 10.6, 10.7 and 10.8, the default event loop is
-:class:`SelectorEventLoop` which uses :class:`selectors.KqueueSelector`.
-:class:`selectors.KqueueSelector` does not support character devices on these
-versions. The :class:`SelectorEventLoop` can be used with
-:class:`~selectors.SelectSelector` or :class:`~selectors.PollSelector` to
-support character devices on these versions of Mac OS X. Example::
-
- import asyncio
- import selectors
-
- selector = selectors.SelectSelector()
- loop = asyncio.SelectorEventLoop(selector)
- asyncio.set_event_loop(loop)
-
-
-Event loop policies and the default policy
-------------------------------------------
-
-Event loop management is abstracted with a *policy* pattern, to provide maximal
-flexibility for custom platforms and frameworks. Throughout the execution of a
-process, a single global policy object manages the event loops available to the
-process based on the calling context. A policy is an object implementing the
-:class:`AbstractEventLoopPolicy` interface.
-
-For most users of :mod:`asyncio`, policies never have to be dealt with
-explicitly, since the default global policy is sufficient (see below).
-
-The module-level functions
-:func:`get_event_loop` and :func:`set_event_loop` provide convenient access to
-event loops managed by the default policy.
-
-
-Event loop policy interface
----------------------------
-
-An event loop policy must implement the following interface:
-
-.. class:: AbstractEventLoopPolicy
-
- Event loop policy.
-
- .. method:: get_event_loop()
-
- Get the event loop for the current context.
-
- Returns an event loop object implementing the :class:`AbstractEventLoop`
- interface.
-
- Raises an exception in case no event loop has been set for the current
- context and the current policy does not specify to create one. It must
- never return ``None``.
-
- .. method:: set_event_loop(loop)
-
- Set the event loop for the current context to *loop*.
-
- .. method:: new_event_loop()
-
- Create and return a new event loop object according to this policy's
- rules.
-
- If there's need to set this loop as the event loop for the current
- context, :meth:`set_event_loop` must be called explicitly.
-
-
-The default policy defines context as the current thread, and manages an event
-loop per thread that interacts with :mod:`asyncio`. An exception to this rule
-happens when :meth:`~AbstractEventLoopPolicy.get_event_loop` is called from a
-running future/coroutine, in which case it will return the current loop
-running that future/coroutine.
-
-If the current thread doesn't already have an event loop associated with it,
-the default policy's :meth:`~AbstractEventLoopPolicy.get_event_loop` method
-creates one when called from the main thread, but raises :exc:`RuntimeError`
-otherwise.
-
-
-Access to the global loop policy
---------------------------------
-
-.. function:: get_event_loop_policy()
-
- Get the current event loop policy.
-
-.. function:: set_event_loop_policy(policy)
-
- Set the current event loop policy. If *policy* is ``None``, the default
- policy is restored.
-
-
-Customizing the event loop policy
----------------------------------
-
-To implement a new event loop policy, it is recommended you subclass the
-concrete default event loop policy :class:`DefaultEventLoopPolicy`
-and override the methods for which you want to change behavior, for example::
-
- class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
-
- def get_event_loop(self):
- """Get the event loop.
-
- This may be None or an instance of EventLoop.
- """
- loop = super().get_event_loop()
- # Do something with loop ...
- return loop
-
- asyncio.set_event_loop_policy(MyEventLoopPolicy())
diff --git a/Doc/library/asyncio-exceptions.rst b/Doc/library/asyncio-exceptions.rst
new file mode 100644
index 00000000000000..e49577a203e8fb
--- /dev/null
+++ b/Doc/library/asyncio-exceptions.rst
@@ -0,0 +1,91 @@
+.. currentmodule:: asyncio
+
+
+.. _asyncio-exceptions:
+
+==========
+Exceptions
+==========
+
+
+.. exception:: TimeoutError
+
+ The operation has exceeded the given deadline.
+
+ .. important::
+ This exception is different from the builtin :exc:`TimeoutError`
+ exception.
+
+
+.. exception:: CancelledError
+
+ The operation has been cancelled.
+
+ This exception can be caught to perform custom operations
+ when asyncio Tasks are cancelled. In almost all situations the
+ exception must be re-raised.
+
+ .. important::
+
+ This exception is a subclass of :exc:`Exception`, so it can be
+ accidentally suppressed by an overly broad ``try..except`` block::
+
+ try:
+ await operation
+ except Exception:
+ # The cancellation is broken because the *except* block
+ # suppresses the CancelledError exception.
+ log.log('an error has occurred')
+
+ Instead, the following pattern should be used::
+
+ try:
+ await operation
+ except asyncio.CancelledError:
+ raise
+ except Exception:
+ log.log('an error has occurred')
+
+
+.. exception:: InvalidStateError
+
+ Invalid internal state of :class:`Task` or :class:`Future`.
+
+ Can be raised in situations like setting a result value for a
+ *Future* object that already has a result value set.
+
+
+.. exception:: SendfileNotAvailableError
+
+ The "sendfile" syscall is not available for the given
+ socket or file type.
+
+ A subclass of :exc:`RuntimeError`.
+
+
+.. exception:: IncompleteReadError
+
+ The requested read operation did not complete fully.
+
+ Raised by the :ref:`asyncio stream APIs`.
+
+ This exception is a subclass of :exc:`EOFError`.
+
+ .. attribute:: expected
+
+ The total number (:class:`int`) of expected bytes.
+
+ .. attribute:: partial
+
+ A string of :class:`bytes` read before the end of stream was reached.
+
+
+.. exception:: LimitOverrunError
+
+ Reached the buffer size limit while looking for a separator.
+
+ Raised by the :ref:`asyncio stream APIs `.
+
+ .. attribute:: consumed
+
+ The total number of to be consumed bytes.
diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst
new file mode 100644
index 00000000000000..6e6e0137c1bdda
--- /dev/null
+++ b/Doc/library/asyncio-future.rst
@@ -0,0 +1,250 @@
+.. currentmodule:: asyncio
+
+
+.. _asyncio-futures:
+
+=======
+Futures
+=======
+
+*Future* objects are used to bridge **low-level callback-based code**
+with high-level async/await code.
+
+
+Future Functions
+================
+
+.. function:: isfuture(obj)
+
+ Return ``True`` if *obj* is either of:
+
+ * an instance of :class:`asyncio.Future`,
+ * an instance of :class:`asyncio.Task`,
+ * a Future-like object with a ``_asyncio_future_blocking``
+ attribute.
+
+ .. versionadded:: 3.5
+
+
+.. function:: ensure_future(obj, \*, loop=None)
+
+ Return:
+
+ * *obj* argument as is, if *obj* is a :class:`Future`,
+ a :class:`Task`, or a Future-like object (:func:`isfuture`
+ is used for the test.)
+
+ * a :class:`Task` object wrapping *obj*, if *obj* is a
+ coroutine (:func:`iscoroutine` is used for the test.)
+
+ * a :class:`Task` object that would await on *obj*, if *obj* is an
+ awaitable (:func:`inspect.isawaitable` is used for the test.)
+
+ If *obj* is neither of the above a :exc:`TypeError` is raised.
+
+ .. important::
+
+ See also the :func:`create_task` function which is the
+ preferred way for creating new Tasks.
+
+ .. versionchanged:: 3.5.1
+ The function accepts any :term:`awaitable` object.
+
+
+.. function:: wrap_future(future, \*, loop=None)
+
+ Wrap a :class:`concurrent.futures.Future` object in a
+ :class:`asyncio.Future` object.
+
+
+Future Object
+=============
+
+.. class:: Future(\*, loop=None)
+
+ A Future represents an eventual result of an asynchronous
+ operation. Not thread-safe.
+
+ Future is an :term:`awaitable` object. Coroutines can await on
+ Future objects until they either have a result or an exception
+ set, or until they are cancelled.
+
+ Typically Futures are used to enable low-level
+ callback-based code (e.g. in protocols implemented using asyncio
+ :ref:`transports `)
+ to interoperate with high-level async/await code.
+
+ The rule of thumb is to never expose Future objects in user-facing
+ APIs, and the recommended way to create a Future object is to call
+ :meth:`loop.create_future`. This way alternative event loop
+ implementations can inject their own optimized implementations
+ of a Future object.
+
+ .. versionchanged:: 3.7
+ Added support for the :mod:`contextvars` module.
+
+ .. method:: result()
+
+ Return the result of the Future.
+
+ If the Future is *done* and has a result set by the
+ :meth:`set_result` method, the result value is returned.
+
+ If the Future is *done* and has an exception set by the
+ :meth:`set_exception` method, this method raises the exception.
+
+ If the Future has been *cancelled*, this method raises
+ a :exc:`CancelledError` exception.
+
+ If the Future's result isn't yet available, this method raises
+ a :exc:`InvalidStateError` exception.
+
+ .. method:: set_result(result)
+
+ Mark the Future as *done* and set its result.
+
+ Raises a :exc:`InvalidStateError` error if the Future is
+ already *done*.
+
+ .. method:: set_exception(exception)
+
+ Mark the Future as *done* and set an exception.
+
+ Raises a :exc:`InvalidStateError` error if the Future is
+ already *done*.
+
+ .. method:: done()
+
+ Return ``True`` if the Future is *done*.
+
+ A Future is *done* if it was *cancelled* or if it has a result
+ or an exception set with :meth:`set_result` or
+ :meth:`set_exception` calls.
+
+ .. method:: cancelled()
+
+ Return ``True`` if the Future was *cancelled*.
+
+ The method is usually used to check if a Future is not
+ *cancelled* before setting a result or an exception for it::
+
+ if not fut.cancelled():
+ fut.set_result(42)
+
+ .. method:: add_done_callback(callback, *, context=None)
+
+ Add a callback to be run when the Future is *done*.
+
+ The *callback* is called with the Future object as its only
+ argument.
+
+ If the Future is already *done* when this method is called,
+ the callback is scheduled with :meth:`loop.call_soon`.
+
+ 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.
+
+ :func:`functools.partial` can be used to pass parameters
+ to the callback, e.g.::
+
+ # Call 'print("Future:", fut)' when "fut" is done.
+ fut.add_done_callback(
+ functools.partial(print, "Future:"))
+
+ .. versionchanged:: 3.7
+ The *context* keyword-only parameter was added.
+ See :pep:`567` for more details.
+
+ .. method:: remove_done_callback(callback)
+
+ Remove *callback* from the callbacks list.
+
+ Returns the number of callbacks removed, which is typically 1,
+ unless a callback was added more than once.
+
+ .. method:: cancel()
+
+ Cancel the Future and schedule callbacks.
+
+ If the Future is already *done* or *cancelled*, return ``False``.
+ Otherwise, change the Future's state to *cancelled*,
+ schedule the callbacks, and return ``True``.
+
+ .. method:: exception()
+
+ Return the exception that was set on this Future.
+
+ The exception (or ``None`` if no exception was set) is
+ returned only if the Future is *done*.
+
+ If the Future has been *cancelled*, this method raises a
+ :exc:`CancelledError` exception.
+
+ If the Future isn't *done* yet, this method raises an
+ :exc:`InvalidStateError` exception.
+
+ .. method:: get_loop()
+
+ Return the event loop the Future object is bound to.
+
+ .. versionadded:: 3.7
+
+
+.. _asyncio_example_future:
+
+This example creates a Future object, creates and schedules an
+asynchronous Task to set result for the Future, and waits until
+the Future has a result::
+
+ async def set_after(fut, delay, value):
+ # Sleep for *delay* seconds.
+ await asyncio.sleep(delay)
+
+ # Set *value* as a result of *fut* Future.
+ fut.set_result(value)
+
+ async def main():
+ # Get the current event loop.
+ loop = asyncio.get_running_loop()
+
+ # Create a new Future object.
+ fut = loop.create_future()
+
+ # Run "set_after()" coroutine in a parallel Task.
+ # We are using the low-level "loop.create_task()" API here because
+ # we already have a reference to the event loop at hand.
+ # Otherwise we could have just used "asyncio.create_task()".
+ loop.create_task(
+ set_after(fut, 1, '... world'))
+
+ print('hello ...')
+
+ # Wait until *fut* has a result (1 second) and print it.
+ print(await fut)
+
+ asyncio.run(main())
+
+
+.. important::
+
+ The Future object was designed to mimic
+ :class:`concurrent.futures.Future`. Key differences include:
+
+ - unlike asyncio Futures, :class:`concurrent.futures.Future`
+ instances cannot be awaited.
+
+ - :meth:`asyncio.Future.result` and :meth:`asyncio.Future.exception`
+ do not accept the *timeout* argument.
+
+ - :meth:`asyncio.Future.result` and :meth:`asyncio.Future.exception`
+ raise an :exc:`InvalidStateError` exception when the Future is not
+ *done*.
+
+ - Callbacks registered with :meth:`asyncio.Future.add_done_callback`
+ are not called immediately. They are scheduled with
+ :meth:`loop.call_soon` instead.
+
+ - asyncio Future is not compatible with the
+ :func:`concurrent.futures.wait` and
+ :func:`concurrent.futures.as_completed` functions.
diff --git a/Doc/library/asyncio-llapi-index.rst b/Doc/library/asyncio-llapi-index.rst
new file mode 100644
index 00000000000000..0ab322af6dc72d
--- /dev/null
+++ b/Doc/library/asyncio-llapi-index.rst
@@ -0,0 +1,510 @@
+.. currentmodule:: asyncio
+
+
+===================
+Low-level API Index
+===================
+
+This page lists all low-level asyncio APIs.
+
+
+Obtaining the Event Loop
+========================
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :func:`asyncio.get_running_loop`
+ - The **preferred** function to get the running event loop.
+
+ * - :func:`asyncio.get_event_loop`
+ - Get an event loop instance (current or via the policy).
+
+ * - :func:`asyncio.set_event_loop`
+ - Set the event loop as current via the current policy.
+
+ * - :func:`asyncio.new_event_loop`
+ - Create a new event loop.
+
+
+.. rubric:: Examples
+
+* :ref:`Using asyncio.get_running_loop() `.
+
+
+Event Loop Methods
+==================
+
+See also the main documentation section about the
+:ref:`event loop methods `.
+
+.. rubric:: Lifecycle
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`loop.run_until_complete`
+ - Run a Future/Task/awaitable until complete.
+
+ * - :meth:`loop.run_forever`
+ - Run the event loop forever.
+
+ * - :meth:`loop.stop`
+ - Stop the event loop.
+
+ * - :meth:`loop.close`
+ - Close the event loop.
+
+ * - :meth:`loop.is_running()`
+ - Return ``True`` if the event loop is running.
+
+ * - :meth:`loop.is_closed()`
+ - Return ``True`` if the event loop is closed.
+
+ * - ``await`` :meth:`loop.shutdown_asyncgens`
+ - Close asynchronous generators.
+
+
+.. rubric:: Debugging
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`loop.set_debug`
+ - Enable or disable the debug mode.
+
+ * - :meth:`loop.get_debug`
+ - Get the current debug mode.
+
+
+.. rubric:: Scheduling Callbacks
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`loop.call_soon`
+ - Invoke a callback soon.
+
+ * - :meth:`loop.call_soon_threadsafe`
+ - A thread-safe variant of :meth:`loop.call_soon`.
+
+ * - :meth:`loop.call_later`
+ - Invoke a callback *after* the given time.
+
+ * - :meth:`loop.call_at`
+ - Invoke a callback *at* the given time.
+
+
+.. rubric:: Thread/Process Pool
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - ``await`` :meth:`loop.run_in_executor`
+ - Run a CPU-bound or other blocking function in
+ a :mod:`concurrent.futures` executor.
+
+ * - :meth:`loop.set_default_executor`
+ - Set the default executor for :meth:`loop.run_in_executor`.
+
+
+.. rubric:: Tasks and Futures
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`loop.create_future`
+ - Create a :class:`Future` object.
+
+ * - :meth:`loop.create_task`
+ - Schedule coroutine as a :class:`Task`.
+
+ * - :meth:`loop.set_task_factory`
+ - Set a factory used by :meth:`loop.create_task` to
+ create :class:`Tasks `.
+
+ * - :meth:`loop.get_task_factory`
+ - Get the factory :meth:`loop.create_task` uses
+ to create :class:`Tasks `.
+
+
+.. rubric:: DNS
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - ``await`` :meth:`loop.getaddrinfo`
+ - Asynchronous version of :meth:`socket.getaddrinfo`.
+
+ * - ``await`` :meth:`loop.getnameinfo`
+ - Asynchronous version of :meth:`socket.getnameinfo`.
+
+
+.. rubric:: Networking and IPC
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - ``await`` :meth:`loop.create_connection`
+ - Open a TCP connection.
+
+ * - ``await`` :meth:`loop.create_server`
+ - Create a TCP server.
+
+ * - ``await`` :meth:`loop.create_unix_connection`
+ - Open a Unix socket connection.
+
+ * - ``await`` :meth:`loop.create_unix_server`
+ - Create a Unix socket server.
+
+ * - ``await`` :meth:`loop.connect_accepted_socket`
+ - Wrap a :class:`~socket.socket` into a ``(transport, protocol)``
+ pair.
+
+ * - ``await`` :meth:`loop.create_datagram_endpoint`
+ - Open a datagram (UDP) connection.
+
+ * - ``await`` :meth:`loop.sendfile`
+ - Send a file over a transport.
+
+ * - ``await`` :meth:`loop.start_tls`
+ - Upgrade an existing connection to TLS.
+
+ * - ``await`` :meth:`loop.connect_read_pipe`
+ - Wrap a read end of a pipe into a ``(transport, protocol)`` pair.
+
+ * - ``await`` :meth:`loop.connect_write_pipe`
+ - Wrap a write end of a pipe into a ``(transport, protocol)`` pair.
+
+
+.. rubric:: Sockets
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - ``await`` :meth:`loop.sock_recv`
+ - Receive data from the :class:`~socket.socket`.
+
+ * - ``await`` :meth:`loop.sock_recv_into`
+ - Receive data from the :class:`~socket.socket` into a buffer.
+
+ * - ``await`` :meth:`loop.sock_sendall`
+ - Send data to the :class:`~socket.socket`.
+
+ * - ``await`` :meth:`loop.sock_connect`
+ - Connect the :class:`~socket.socket`.
+
+ * - ``await`` :meth:`loop.sock_accept`
+ - Accept a :class:`~socket.socket` connection.
+
+ * - ``await`` :meth:`loop.sock_sendfile`
+ - Send a file over the :class:`~socket.socket`.
+
+ * - :meth:`loop.add_reader`
+ - Start watching a file descriptor for read availability.
+
+ * - :meth:`loop.remove_reader`
+ - Stop watching a file descriptor for read availability.
+
+ * - :meth:`loop.add_writer`
+ - Start watching a file descriptor for write availability.
+
+ * - :meth:`loop.remove_writer`
+ - Stop watching a file descriptor for write availability.
+
+
+.. rubric:: Unix Signals
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`loop.add_signal_handler`
+ - Add a handler for a :mod:`signal`.
+
+ * - :meth:`loop.remove_signal_handler`
+ - Remove a handler for a :mod:`signal`.
+
+
+.. rubric:: Subprocesses
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`loop.subprocess_exec`
+ - Spawn a subprocess.
+
+ * - :meth:`loop.subprocess_shell`
+ - Spawn a subprocess from a shell command.
+
+
+.. rubric:: Error Handling
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`loop.call_exception_handler`
+ - Call the exception handler.
+
+ * - :meth:`loop.set_exception_handler`
+ - Set a new exception handler.
+
+ * - :meth:`loop.get_exception_handler`
+ - Get the current exception handler.
+
+ * - :meth:`loop.default_exception_handler`
+ - The default exception handler implementation.
+
+
+.. rubric:: Examples
+
+* :ref:`Using asyncio.get_event_loop() and loop.run_forever()
+ `.
+
+* :ref:`Using loop.call_later() `.
+
+* Using ``loop.create_connection()`` to implement
+ :ref:`an echo-client `.
+
+* Using ``loop.create_connection()`` to
+ :ref:`connect a socket `.
+
+* :ref:`Using add_reader() to watch an FD for read events
+ `.
+
+* :ref:`Using loop.add_signal_handler() `.
+
+* :ref:`Using loop.subprocess_exec() `.
+
+
+Transports
+==========
+
+All transports implement the following methods:
+
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`transport.close() `
+ - Close the transport.
+
+ * - :meth:`transport.is_closing() `
+ - Return ``True`` if the transport is closing or is closed.
+
+ * - :meth:`transport.get_extra_info() `
+ - Request for information about the transport.
+
+ * - :meth:`transport.set_protocol() `
+ - Set a new protocol.
+
+ * - :meth:`transport.get_protocol() `
+ - Return the current protocol.
+
+
+Transports that can receive data (TCP and Unix connections,
+pipes, etc). Returned from methods like
+:meth:`loop.create_connection`, :meth:`loop.create_unix_connection`,
+:meth:`loop.connect_read_pipe`, etc:
+
+.. rubric:: Read Transports
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`transport.is_reading() `
+ - Return ``True`` if the transport is receiving.
+
+ * - :meth:`transport.pause_reading() `
+ - Pause receiving.
+
+ * - :meth:`transport.resume_reading() `
+ - Resume receiving.
+
+
+Transports that can Send data (TCP and Unix connections,
+pipes, etc). Returned from methods like
+:meth:`loop.create_connection`, :meth:`loop.create_unix_connection`,
+:meth:`loop.connect_write_pipe`, etc:
+
+.. rubric:: Write Transports
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`transport.write() `
+ - Write data to the transport.
+
+ * - :meth:`transport.writelines() `
+ - Write buffers to the transport.
+
+ * - :meth:`transport.can_write_eof() `
+ - Return :const:`True` if the transport supports sending EOF.
+
+ * - :meth:`transport.write_eof() `
+ - Close and send EOF after flushing buffered data.
+
+ * - :meth:`transport.abort() `
+ - Close the transport immediately.
+
+ * - :meth:`transport.get_write_buffer_size()
+ `
+ - Return high and low water marks for write flow control.
+
+ * - :meth:`transport.set_write_buffer_limits()
+ `
+ - Set new high and low water marks for write flow control.
+
+
+Transports returned by :meth:`loop.create_datagram_endpoint`:
+
+.. rubric:: Datagram Transports
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`transport.sendto() `
+ - Send data to the remote peer.
+
+ * - :meth:`transport.abort() `
+ - Close the transport immediately.
+
+
+Low-level transport abstraction over subprocesses.
+Returned by :meth:`loop.subprocess_exec` and
+:meth:`loop.subprocess_shell`:
+
+.. rubric:: Subprocess Transports
+.. list-table::
+ :widths: 50 50
+ :class: full-width-table
+
+ * - :meth:`transport.get_pid() `
+ - Return the subprocess process id.
+
+ * - :meth:`transport.get_pipe_transport()
+ `
+ - Return the transport for the requested communication pipe
+ (*stdin*, *stdout*, or *stderr*).
+
+ * - :meth:`transport.get_returncode() `
+ - Return the subprocess return code.
+
+ * - :meth:`transport.kill() `
+ - Kill the subprocess.
+
+ * - :meth:`transport.send_signal() `
+ - Send a signal to the subprocess.
+
+ * - :meth:`transport.terminate() `
+ - Stop the subprocess.
+
+ * - :meth:`transport.close()