mirror of
https://github.com/python/cpython.git
synced 2025-12-23 09:19:18 +00:00
Merge branch 'main' into bpo-45509
This commit is contained in:
commit
2dfc96c6e3
2882 changed files with 332598 additions and 209731 deletions
|
|
@ -1,14 +1,14 @@
|
|||
variables:
|
||||
coverage: false
|
||||
|
||||
trigger: ['main', '3.10', '3.9', '3.8', '3.7']
|
||||
trigger: ['main', '3.11', '3.10', '3.9', '3.8', '3.7']
|
||||
|
||||
jobs:
|
||||
- job: Prebuild
|
||||
displayName: Pre-build checks
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- template: ./prebuild-checks.yml
|
||||
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- template: ./docs-steps.yml
|
||||
|
|
@ -52,12 +52,12 @@ jobs:
|
|||
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
variables:
|
||||
testRunTitle: '$(build.sourceBranchName)-linux'
|
||||
testRunPlatform: linux
|
||||
openssl_version: 1.1.1l
|
||||
openssl_version: 1.1.1q
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
|
@ -78,12 +78,12 @@ jobs:
|
|||
)
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
variables:
|
||||
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
|
||||
testRunPlatform: linux-coverage
|
||||
openssl_version: 1.1.1l
|
||||
openssl_version: 1.1.1q
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
|
@ -98,7 +98,7 @@ jobs:
|
|||
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
vmImage: windows-2022
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
# Locate a set of the tools used for builds
|
||||
|
||||
steps:
|
||||
- template: windows-release/find-sdk.yml
|
||||
parameters:
|
||||
toolname: 'signtool.exe'
|
||||
|
||||
- powershell: |
|
||||
$vcvarsall = (& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
|
||||
-prerelease `
|
||||
-latest `
|
||||
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
|
||||
-find VC\Auxiliary\Build\vcvarsall.bat)
|
||||
Write-Host "Found vcvarsall at $vcvarsall"
|
||||
Write-Host "##vso[task.setVariable variable=vcvarsall]$vcvarsall"
|
||||
displayName: 'Find vcvarsall.bat'
|
||||
|
||||
- powershell: |
|
||||
$msbuild = (& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
|
||||
-prerelease `
|
||||
-latest `
|
||||
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
|
||||
-find MSBuild\Current\Bin\msbuild.exe)
|
||||
Write-Host "Found MSBuild at $msbuild"
|
||||
Write-Host "##vso[task.setVariable variable=msbuild]$msbuild"
|
||||
displayName: 'Find MSBuild'
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
name: $(SourceTag)_$(Date:yyyyMMdd)$(Rev:.rr)
|
||||
|
||||
variables:
|
||||
IntDir: '$(Build.BinariesDirectory)'
|
||||
OutDir: '$(Build.ArtifactStagingDirectory)'
|
||||
|
||||
# MUST BE SET AT QUEUE TIME
|
||||
# SigningCertificate: 'Python Software Foundation'
|
||||
# SourcesRepo: 'https://github.com/python/cpython-source-deps'
|
||||
# SourceTag: 'libffi-3.4.2'
|
||||
|
||||
jobs:
|
||||
- job: Build_LibFFI
|
||||
displayName: LibFFI
|
||||
pool:
|
||||
vmImage: windows-latest
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- template: ./find-tools.yml
|
||||
|
||||
- powershell: |
|
||||
mkdir -Force "$(IntDir)\script"
|
||||
iwr "https://github.com/python/cpython/raw/main/PCbuild/prepare_libffi.bat" `
|
||||
-outfile "$(IntDir)\script\prepare_libffi.bat"
|
||||
displayName: 'Download build script'
|
||||
|
||||
- powershell: |
|
||||
git clone $(SourcesRepo) -b $(SourceTag) --depth 1 -c core.autocrlf=false -c core.eol=lf .
|
||||
displayName: 'Check out LibFFI sources'
|
||||
|
||||
- script: 'prepare_libffi.bat --install-cygwin'
|
||||
workingDirectory: '$(IntDir)\script'
|
||||
displayName: 'Install Cygwin and build'
|
||||
env:
|
||||
VCVARSALL: '$(vcvarsall)'
|
||||
LIBFFI_SOURCE: '$(Build.SourcesDirectory)'
|
||||
LIBFFI_OUT: '$(OutDir)'
|
||||
|
||||
- powershell: |
|
||||
if ((gci *\*.dll).Count -lt 4) {
|
||||
Write-Error "Did not generate enough DLL files"
|
||||
}
|
||||
if ((gci *\Include\ffi.h).Count -lt 4) {
|
||||
Write-Error "Did not generate enough include files"
|
||||
}
|
||||
failOnStderr: true
|
||||
workingDirectory: '$(OutDir)'
|
||||
displayName: 'Verify files were created'
|
||||
|
||||
- publish: '$(OutDir)'
|
||||
artifact: 'unsigned'
|
||||
displayName: 'Publish unsigned build'
|
||||
|
||||
- job: Sign_LibFFI
|
||||
displayName: Sign LibFFI
|
||||
dependsOn: Build_LibFFI
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
- download: current
|
||||
artifact: unsigned
|
||||
|
||||
- template: ./find-tools.yml
|
||||
|
||||
- powershell: |
|
||||
signtool sign /q /a `
|
||||
/n "Python Software Foundation" `
|
||||
/fd sha256 `
|
||||
/tr http://timestamp.digicert.com/ /td sha256 `
|
||||
/d "LibFFI for Python" `
|
||||
(gci "$(Pipeline.Workspace)\unsigned\*.dll" -r)
|
||||
displayName: 'Sign files'
|
||||
|
||||
- publish: '$(Pipeline.Workspace)\unsigned'
|
||||
artifact: 'libffi'
|
||||
displayName: 'Publish libffi'
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
name: $(SourceTag)_$(Date:yyyyMMdd)$(Rev:.rr)
|
||||
|
||||
variables:
|
||||
IntDir: '$(Build.BinariesDirectory)'
|
||||
OutDir: '$(Build.ArtifactStagingDirectory)'
|
||||
|
||||
# MUST BE SET AT QUEUE TIME
|
||||
# SigningCertificate: 'Python Software Foundation'
|
||||
# SourcesRepo: 'https://github.com/python/cpython-source-deps'
|
||||
# SourceTag: 'openssl-1.1.1k'
|
||||
|
||||
jobs:
|
||||
- job: Build_SSL
|
||||
displayName: OpenSSL
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
#vmImage: windows-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Platform: 'win32'
|
||||
VCPlatform: 'amd64_x86'
|
||||
OpenSSLPlatform: 'VC-WIN32 no-asm'
|
||||
amd64:
|
||||
Platform: 'amd64'
|
||||
VCPlatform: 'amd64'
|
||||
OpenSSLPlatform: 'VC-WIN64A-masm'
|
||||
arm32:
|
||||
Platform: 'arm32'
|
||||
VCPlatform: 'amd64_arm'
|
||||
OpenSSLPlatform: 'VC-WIN32-ARM'
|
||||
arm64:
|
||||
Platform: 'arm64'
|
||||
VCPlatform: 'amd64_arm64'
|
||||
OpenSSLPlatform: 'VC-WIN64-ARM'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- template: ./find-tools.yml
|
||||
|
||||
- powershell: |
|
||||
git clone $(SourcesRepo) -b $(SourceTag) --depth 1 .
|
||||
displayName: 'Check out OpenSSL sources'
|
||||
|
||||
- powershell: |
|
||||
$f = gi ms\uplink.c
|
||||
$c1 = gc $f
|
||||
$c2 = $c1 -replace '\(\(h = GetModuleHandle\(NULL\)\) == NULL\)', '((h = GetModuleHandleA("_ssl.pyd")) == NULL) if ((h = GetModuleHandleA("_ssl_d.pyd")) == NULL) if ((h = GetModuleHandle(NULL)) == NULL /*patched*/)'
|
||||
if ($c2 -ne $c1) {
|
||||
$c2 | Out-File $f -Encoding ASCII
|
||||
} else {
|
||||
Write-Host '##warning Failed to patch uplink.c'
|
||||
}
|
||||
displayName: 'Apply uplink.c patch'
|
||||
|
||||
- script: |
|
||||
call "$(vcvarsall)" $(VCPlatform)
|
||||
perl "$(Build.SourcesDirectory)\Configure" $(OpenSSLPlatform)
|
||||
nmake
|
||||
workingDirectory: '$(IntDir)'
|
||||
displayName: 'Build OpenSSL'
|
||||
|
||||
- script: |
|
||||
call "$(vcvarsall)" $(VCPlatform)
|
||||
signtool sign /q /a /n "$(SigningCertificate)" /fd sha256 /tr http://timestamp.digicert.com/ /td sha256 /d "OpenSSL for Python" *.dll
|
||||
workingDirectory: '$(IntDir)'
|
||||
displayName: 'Sign OpenSSL Build'
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy built libraries for upload'
|
||||
inputs:
|
||||
SourceFolder: '$(IntDir)'
|
||||
Contents: |
|
||||
lib*.dll
|
||||
lib*.pdb
|
||||
lib*.lib
|
||||
include\openssl\*.h
|
||||
TargetFolder: '$(OutDir)'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy header files for upload'
|
||||
inputs:
|
||||
SourceFolder: '$(Build.SourcesDirectory)'
|
||||
Contents: |
|
||||
include\openssl\*
|
||||
TargetFolder: '$(OutDir)'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy applink files for upload'
|
||||
inputs:
|
||||
SourceFolder: '$(Build.SourcesDirectory)\ms'
|
||||
Contents: applink.c
|
||||
TargetFolder: '$(OutDir)\include'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy LICENSE for upload'
|
||||
inputs:
|
||||
SourceFolder: '$(Build.SourcesDirectory)'
|
||||
Contents: LICENSE
|
||||
TargetFolder: '$(OutDir)'
|
||||
|
||||
- publish: '$(OutDir)'
|
||||
artifact: '$(Platform)'
|
||||
displayName: 'Publishing $(Platform)'
|
||||
|
|
@ -66,7 +66,9 @@ steps:
|
|||
COMMAND: make
|
||||
|
||||
- ${{ if eq(parameters.patchcheck, 'true') }}:
|
||||
- script: ./python Tools/scripts/patchcheck.py --travis true
|
||||
- script: |
|
||||
git fetch origin
|
||||
./python Tools/patchcheck/patchcheck.py --ci true
|
||||
displayName: 'Run patchcheck.py'
|
||||
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
variables:
|
||||
coverage: false
|
||||
|
||||
pr: ['main', '3.10', '3.9', '3.8', '3.7']
|
||||
pr: ['main', '3.11', '3.10', '3.9', '3.8', '3.7']
|
||||
|
||||
jobs:
|
||||
- job: Prebuild
|
||||
displayName: Pre-build checks
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- template: ./prebuild-checks.yml
|
||||
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- template: ./docs-steps.yml
|
||||
|
|
@ -52,12 +52,12 @@ jobs:
|
|||
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
variables:
|
||||
testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
|
||||
testRunPlatform: linux
|
||||
openssl_version: 1.1.1l
|
||||
openssl_version: 1.1.1q
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
|
@ -78,12 +78,12 @@ jobs:
|
|||
)
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
vmImage: ubuntu-22.04
|
||||
|
||||
variables:
|
||||
testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
|
||||
testRunPlatform: linux-coverage
|
||||
openssl_version: 1.1.1l
|
||||
openssl_version: 1.1.1q
|
||||
|
||||
steps:
|
||||
- template: ./posix-steps.yml
|
||||
|
|
@ -98,7 +98,7 @@ jobs:
|
|||
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
vmImage: windows-2022
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
name: tcl$(TkSourceTag)_$(Date:yyyyMMdd)$(Rev:.rr)
|
||||
|
||||
variables:
|
||||
IntDir: '$(Build.BinariesDirectory)\obj'
|
||||
ExternalsDir: '$(Build.BinariesDirectory)\externals'
|
||||
OutDir: '$(Build.ArtifactStagingDirectory)'
|
||||
Configuration: 'Release'
|
||||
|
||||
# MUST BE SET AT QUEUE TIME
|
||||
# SigningCertificate: 'Python Software Foundation'
|
||||
# SourcesRepo: 'https://github.com/python/cpython-source-deps'
|
||||
# TclSourceTag: 'tcl-core-8.6.12.0'
|
||||
# TkSourceTag: 'tk-8.6.12.0'
|
||||
# TixSourceTag: 'tix-8.4.3.6'
|
||||
|
||||
jobs:
|
||||
- job: Build_TclTk
|
||||
displayName: 'Tcl/Tk'
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
#vmImage: windows-latest
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: ./find-tools.yml
|
||||
|
||||
- powershell: |
|
||||
git clone $(SourcesRepo) -b $(TclSourceTag) --depth 1 "$(ExternalsDir)\$(TclSourceTag)"
|
||||
displayName: 'Check out Tcl sources'
|
||||
|
||||
- powershell: |
|
||||
git clone $(SourcesRepo) -b $(TkSourceTag) --depth 1 "$(ExternalsDir)\$(TkSourceTag)"
|
||||
displayName: 'Check out Tk sources'
|
||||
|
||||
- powershell: |
|
||||
git clone $(SourcesRepo) -b $(TixSourceTag) --depth 1 "$(ExternalsDir)\$(TixSourceTag)"
|
||||
displayName: 'Check out Tix sources'
|
||||
|
||||
# This msbuild.rsp file will be used by the build to forcibly override these variables
|
||||
- powershell: |
|
||||
del -Force -EA 0 msbuild.rsp
|
||||
"/p:IntDir=$(IntDir)\" >> msbuild.rsp
|
||||
"/p:ExternalsDir=$(ExternalsDir)\" >> msbuild.rsp
|
||||
"/p:tclDir=$(ExternalsDir)\$(TclSourceTag)\" >> msbuild.rsp
|
||||
"/p:tkDir=$(ExternalsDir)\$(TkSourceTag)\" >> msbuild.rsp
|
||||
"/p:tixDir=$(ExternalsDir)\$(TixSourceTag)\" >> msbuild.rsp
|
||||
displayName: 'Generate msbuild.rsp'
|
||||
|
||||
- powershell: |
|
||||
& "$(msbuild)" PCbuild\tcl.vcxproj "@msbuild.rsp" /p:Platform=Win32 /p:tcltkDir="$(OutDir)\win32"
|
||||
& "$(msbuild)" PCbuild\tk.vcxproj "@msbuild.rsp" /p:Platform=Win32 /p:tcltkDir="$(OutDir)\win32"
|
||||
& "$(msbuild)" PCbuild\tix.vcxproj "@msbuild.rsp" /p:Platform=Win32 /p:tcltkDir="$(OutDir)\win32"
|
||||
displayName: 'Build for win32'
|
||||
|
||||
- powershell: |
|
||||
& "$(msbuild)" PCbuild\tcl.vcxproj "@msbuild.rsp" /p:Platform=x64 /p:tcltkDir="$(OutDir)\amd64"
|
||||
& "$(msbuild)" PCbuild\tk.vcxproj "@msbuild.rsp" /p:Platform=x64 /p:tcltkDir="$(OutDir)\amd64"
|
||||
& "$(msbuild)" PCbuild\tix.vcxproj "@msbuild.rsp" /p:Platform=x64 /p:tcltkDir="$(OutDir)\amd64"
|
||||
displayName: 'Build for amd64'
|
||||
|
||||
- publish: '$(OutDir)'
|
||||
artifact: 'tcltk'
|
||||
displayName: 'Publishing tcltk'
|
||||
|
|
@ -12,7 +12,7 @@ steps:
|
|||
displayName: Show layout info (${{ parameters.kind }})
|
||||
|
||||
- ${{ if eq(parameters.fulltest, 'true') }}:
|
||||
- script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)"
|
||||
- script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)" -i test_launcher
|
||||
workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
|
||||
displayName: ${{ parameters.kind }} Tests
|
||||
env:
|
||||
|
|
|
|||
|
|
@ -1,129 +0,0 @@
|
|||
name: Release_$(Build.SourceBranchName)_$(SourceTag)_$(Date:yyyyMMdd)$(Rev:.rr)
|
||||
|
||||
variables:
|
||||
__RealSigningCertificate: 'Python Software Foundation'
|
||||
# QUEUE TIME VARIABLES
|
||||
# GitRemote: python
|
||||
# SourceTag:
|
||||
# DoPGO: true
|
||||
# SigningCertificate: 'Python Software Foundation'
|
||||
# SigningDescription: 'Built: $(Build.BuildNumber)'
|
||||
# DoLayout: true
|
||||
# DoMSIX: true
|
||||
# DoNuget: true
|
||||
# DoEmbed: true
|
||||
# DoMSI: true
|
||||
# DoPublish: false
|
||||
# PyDotOrgUsername: ''
|
||||
# PyDotOrgServer: ''
|
||||
# BuildToPublish: ''
|
||||
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
displayName: Build binaries
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-build.yml
|
||||
|
||||
- stage: Sign
|
||||
displayName: Sign binaries
|
||||
dependsOn: Build
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-sign.yml
|
||||
|
||||
- stage: Layout
|
||||
displayName: Generate layouts
|
||||
dependsOn: Sign
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-layout-full.yml
|
||||
- template: windows-release/stage-layout-embed.yml
|
||||
- template: windows-release/stage-layout-nuget.yml
|
||||
|
||||
- stage: Pack
|
||||
dependsOn: Layout
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-pack-nuget.yml
|
||||
|
||||
- stage: Test
|
||||
dependsOn: Pack
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-test-embed.yml
|
||||
- template: windows-release/stage-test-nuget.yml
|
||||
|
||||
- stage: Layout_MSIX
|
||||
displayName: Generate MSIX layouts
|
||||
dependsOn: Sign
|
||||
condition: and(succeeded(), and(eq(variables['DoMSIX'], 'true'), not(variables['BuildToPublish'])))
|
||||
jobs:
|
||||
- template: windows-release/stage-layout-msix.yml
|
||||
|
||||
- stage: Pack_MSIX
|
||||
displayName: Package MSIX
|
||||
dependsOn: Layout_MSIX
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-pack-msix.yml
|
||||
|
||||
- stage: Build_MSI
|
||||
displayName: Build MSI installer
|
||||
dependsOn: Sign
|
||||
condition: and(succeeded(), and(eq(variables['DoMSI'], 'true'), not(variables['BuildToPublish'])))
|
||||
jobs:
|
||||
- template: windows-release/stage-msi.yml
|
||||
|
||||
- stage: Test_MSI
|
||||
displayName: Test MSI installer
|
||||
dependsOn: Build_MSI
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-test-msi.yml
|
||||
|
||||
- stage: PublishPyDotOrg
|
||||
displayName: Publish to python.org
|
||||
dependsOn: ['Test_MSI', 'Test']
|
||||
condition: and(succeeded(), and(eq(variables['DoPublish'], 'true'), not(variables['BuildToPublish'])))
|
||||
jobs:
|
||||
- template: windows-release/stage-publish-pythonorg.yml
|
||||
|
||||
- stage: PublishNuget
|
||||
displayName: Publish to nuget.org
|
||||
dependsOn: Test
|
||||
condition: and(succeeded(), and(eq(variables['DoPublish'], 'true'), not(variables['BuildToPublish'])))
|
||||
jobs:
|
||||
- template: windows-release/stage-publish-nugetorg.yml
|
||||
|
||||
- stage: PublishStore
|
||||
displayName: Publish to Store
|
||||
dependsOn: Pack_MSIX
|
||||
condition: and(succeeded(), and(eq(variables['DoPublish'], 'true'), not(variables['BuildToPublish'])))
|
||||
jobs:
|
||||
- template: windows-release/stage-publish-store.yml
|
||||
|
||||
|
||||
- stage: PublishExistingPyDotOrg
|
||||
displayName: Publish existing build to python.org
|
||||
dependsOn: []
|
||||
condition: and(succeeded(), and(eq(variables['DoPublish'], 'true'), variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-publish-pythonorg.yml
|
||||
|
||||
- stage: PublishExistingNuget
|
||||
displayName: Publish existing build to nuget.org
|
||||
dependsOn: []
|
||||
condition: and(succeeded(), and(eq(variables['DoPublish'], 'true'), variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-publish-nugetorg.yml
|
||||
|
||||
- stage: PublishExistingStore
|
||||
displayName: Publish existing build to Store
|
||||
dependsOn: []
|
||||
condition: and(succeeded(), and(eq(variables['DoPublish'], 'true'), variables['BuildToPublish']))
|
||||
jobs:
|
||||
- template: windows-release/stage-publish-store.yml
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
parameters:
|
||||
ShouldPGO: false
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- powershell: |
|
||||
$d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }};
|
||||
Write-Host "##vso[task.setvariable variable=VersionText]$($d.PythonVersion)"
|
||||
Write-Host "##vso[task.setvariable variable=VersionNumber]$($d.PythonVersionNumber)"
|
||||
Write-Host "##vso[task.setvariable variable=VersionHex]$($d.PythonVersionHex)"
|
||||
Write-Host "##vso[task.setvariable variable=VersionUnique]$($d.PythonVersionUnique)"
|
||||
Write-Host "##vso[build.addbuildtag]$($d.PythonVersion)"
|
||||
Write-Host "##vso[build.addbuildtag]$($d.PythonVersion)-$(Name)"
|
||||
displayName: 'Extract version numbers'
|
||||
|
||||
- ${{ if eq(parameters.ShouldPGO, 'false') }}:
|
||||
- powershell: |
|
||||
$env:SigningCertificate = $null
|
||||
.\PCbuild\build.bat -v -p $(Platform) -c $(Configuration)
|
||||
displayName: 'Run build'
|
||||
env:
|
||||
IncludeUwp: true
|
||||
Py_OutDir: '$(Build.BinariesDirectory)\bin'
|
||||
|
||||
- ${{ if eq(parameters.ShouldPGO, 'true') }}:
|
||||
- powershell: |
|
||||
$env:SigningCertificate = $null
|
||||
.\PCbuild\build.bat -v -p $(Platform) --pgo
|
||||
displayName: 'Run build with PGO'
|
||||
env:
|
||||
IncludeUwp: true
|
||||
Py_OutDir: '$(Build.BinariesDirectory)\bin'
|
||||
|
||||
- powershell: |
|
||||
$kitroot = (gp 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\').KitsRoot10
|
||||
$tool = (gci -r "$kitroot\Bin\*\x64\signtool.exe" | sort FullName -Desc | select -First 1)
|
||||
if (-not $tool) {
|
||||
throw "SDK is not available"
|
||||
}
|
||||
Write-Host "##vso[task.prependpath]$($tool.Directory)"
|
||||
displayName: 'Add WinSDK tools to path'
|
||||
|
||||
- powershell: |
|
||||
$env:SigningCertificate = $null
|
||||
$(_HostPython) PC\layout -vv -b "$(Build.BinariesDirectory)\bin" -t "$(Build.BinariesDirectory)\catalog" --catalog "${env:CAT}.cdf" --preset-default --arch $(Arch)
|
||||
makecat "${env:CAT}.cdf"
|
||||
del "${env:CAT}.cdf"
|
||||
if (-not (Test-Path "${env:CAT}.cat")) {
|
||||
throw "Failed to build catalog file"
|
||||
}
|
||||
displayName: 'Generate catalog'
|
||||
env:
|
||||
CAT: $(Build.BinariesDirectory)\bin\$(Arch)\python
|
||||
PYTHON_HEXVERSION: $(VersionHex)
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish binaries'
|
||||
condition: and(succeeded(), not(and(eq(variables['Configuration'], 'Release'), variables['SigningCertificate'])))
|
||||
inputs:
|
||||
targetPath: '$(Build.BinariesDirectory)\bin\$(Arch)'
|
||||
artifactName: bin_$(Name)
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish binaries for signing'
|
||||
condition: and(succeeded(), and(eq(variables['Configuration'], 'Release'), variables['SigningCertificate']))
|
||||
inputs:
|
||||
targetPath: '$(Build.BinariesDirectory)\bin\$(Arch)'
|
||||
artifactName: unsigned_bin_$(Name)
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Layout Artifact: symbols'
|
||||
inputs:
|
||||
sourceFolder: $(Build.BinariesDirectory)\bin\$(Arch)
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\symbols\$(Name)
|
||||
flatten: true
|
||||
contents: |
|
||||
**\*.pdb
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: symbols'
|
||||
inputs:
|
||||
PathToPublish: '$(Build.ArtifactStagingDirectory)\symbols'
|
||||
ArtifactName: symbols
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
parameters:
|
||||
depth: 3
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(SourceTag) --single-branch https://github.com/$(GitRemote)/cpython.git .
|
||||
displayName: 'git clone ($(GitRemote)/$(SourceTag))'
|
||||
condition: and(succeeded(), and(variables['GitRemote'], variables['SourceTag']))
|
||||
|
||||
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(SourceTag) --single-branch $(Build.Repository.Uri) .
|
||||
displayName: 'git clone (<default>/$(SourceTag))'
|
||||
condition: and(succeeded(), and(not(variables['GitRemote']), variables['SourceTag']))
|
||||
|
||||
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(Build.SourceBranchName) --single-branch https://github.com/$(GitRemote)/cpython.git .
|
||||
displayName: 'git clone ($(GitRemote)/<default>)'
|
||||
condition: and(succeeded(), and(variables['GitRemote'], not(variables['SourceTag'])))
|
||||
|
||||
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(Build.SourceBranchName) --single-branch $(Build.Repository.Uri) .
|
||||
displayName: 'git clone'
|
||||
condition: and(succeeded(), and(not(variables['GitRemote']), not(variables['SourceTag'])))
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Locate the Windows SDK and add its binaries directory to PATH
|
||||
#
|
||||
# `toolname` can be overridden to use a different marker file.
|
||||
|
||||
parameters:
|
||||
toolname: signtool.exe
|
||||
|
||||
steps:
|
||||
- powershell: |
|
||||
$kitroot = (gp 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\').KitsRoot10
|
||||
$tool = (gci -r "$kitroot\Bin\*\${{ parameters.toolname }}" | sort FullName -Desc | select -First 1)
|
||||
if (-not $tool) {
|
||||
throw "SDK is not available"
|
||||
}
|
||||
Write-Host "##vso[task.prependpath]$($tool.Directory)"
|
||||
Write-Host "Adding $($tool.Directory) to PATH"
|
||||
displayName: 'Add WinSDK tools to path'
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
parameters:
|
||||
GPGKeyFile: $(GPGKey)
|
||||
GPGPassphrase: $(GPGPassphrase)
|
||||
Files: '*'
|
||||
WorkingDirectory: $(Build.BinariesDirectory)
|
||||
|
||||
steps:
|
||||
- task: DownloadSecureFile@1
|
||||
name: gpgkey
|
||||
inputs:
|
||||
secureFile: ${{ parameters.GPGKeyFile }}
|
||||
displayName: 'Download GPG key'
|
||||
|
||||
- powershell: |
|
||||
git clone https://github.com/python/cpython-bin-deps --branch gpg --single-branch --depth 1 --progress -v "gpg"
|
||||
gpg/gpg2.exe --import "$(gpgkey.secureFilePath)"
|
||||
(gci -File ${{ parameters.Files }}).FullName | %{
|
||||
gpg/gpg2.exe -ba --batch --passphrase ${{ parameters.GPGPassphrase }} $_
|
||||
"Made signature for $_"
|
||||
}
|
||||
displayName: 'Generate GPG signatures'
|
||||
workingDirectory: ${{ parameters.WorkingDirectory }}
|
||||
|
||||
- powershell: |
|
||||
$p = gps "gpg-agent" -EA 0
|
||||
if ($p) { $p.Kill() }
|
||||
displayName: 'Kill GPG agent'
|
||||
condition: true
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
steps:
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_$(HostArch)'
|
||||
condition: and(succeeded(), variables['HostArch'])
|
||||
inputs:
|
||||
artifactName: bin_$(HostArch)
|
||||
targetPath: $(Build.BinariesDirectory)\bin_$(HostArch)
|
||||
|
||||
- powershell: >
|
||||
Write-Host (
|
||||
'##vso[task.setvariable variable=LayoutCmd]&
|
||||
"$(Python)"
|
||||
"{1}\PC\layout"
|
||||
-vv
|
||||
--source "{1}"
|
||||
--build "{0}\bin"
|
||||
--arch "$(Name)"
|
||||
--temp "{0}\layout-temp"
|
||||
--include-cat "{0}\bin\python.cat"
|
||||
--doc-build "{0}\doc"'
|
||||
-f ("$(Build.BinariesDirectory)", "$(Build.SourcesDirectory)")
|
||||
)
|
||||
displayName: 'Set LayoutCmd'
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
parameters:
|
||||
DllToolOpt: -m i386:x86-64
|
||||
#DllToolOpt: -m i386 --as-flags=--32
|
||||
|
||||
steps:
|
||||
- powershell: |
|
||||
git clone https://github.com/python/cpython-bin-deps --branch binutils --single-branch --depth 1 --progress -v "binutils"
|
||||
gci "bin\$(Arch)\python*.dll" | %{
|
||||
& "binutils\gendef.exe" $_ | Out-File -Encoding ascii tmp.def
|
||||
& "binutils\dlltool.exe" --dllname $($_.BaseName).dll --def tmp.def --output-lib "$($_.Directory)\lib$($_.BaseName).a" ${{ parameters.DllToolOpt }}
|
||||
}
|
||||
displayName: 'Generate MinGW import library'
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- powershell: |
|
||||
$d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }};
|
||||
Write-Host "##vso[task.setvariable variable=SigningDescription]Python $($d.PythonVersion)"
|
||||
displayName: 'Update signing description'
|
||||
condition: and(succeeded(), not(variables['SigningDescription']))
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: doc'
|
||||
inputs:
|
||||
artifactName: doc
|
||||
targetPath: $(Build.BinariesDirectory)\doc
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Merge documentation files'
|
||||
inputs:
|
||||
sourceFolder: $(Build.BinariesDirectory)\doc
|
||||
targetFolder: $(Build.SourcesDirectory)\Doc\build
|
||||
contents: |
|
||||
htmlhelp\*.chm
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_win32'
|
||||
inputs:
|
||||
artifactName: bin_win32
|
||||
targetPath: $(Build.BinariesDirectory)\win32
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_win32_d'
|
||||
inputs:
|
||||
artifactName: bin_win32_d
|
||||
targetPath: $(Build.BinariesDirectory)\win32
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_amd64'
|
||||
inputs:
|
||||
artifactName: bin_amd64
|
||||
targetPath: $(Build.BinariesDirectory)\amd64
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_amd64_d'
|
||||
inputs:
|
||||
artifactName: bin_amd64_d
|
||||
targetPath: $(Build.BinariesDirectory)\amd64
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: tcltk_lib_win32'
|
||||
inputs:
|
||||
artifactName: tcltk_lib_win32
|
||||
targetPath: $(Build.BinariesDirectory)\tcltk_lib_win32
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: tcltk_lib_amd64'
|
||||
inputs:
|
||||
artifactName: tcltk_lib_amd64
|
||||
targetPath: $(Build.BinariesDirectory)\tcltk_lib_amd64
|
||||
|
||||
- powershell: |
|
||||
copy $(Build.BinariesDirectory)\amd64\Activate.ps1 Lib\venv\scripts\common\Activate.ps1 -Force
|
||||
displayName: 'Copy signed files into sources'
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
- script: |
|
||||
call Tools\msi\get_externals.bat
|
||||
call PCbuild\find_python.bat
|
||||
echo ##vso[task.setvariable variable=PYTHON]%PYTHON%
|
||||
call PCbuild/find_msbuild.bat
|
||||
echo ##vso[task.setvariable variable=MSBUILD]%MSBUILD%
|
||||
displayName: 'Get external dependencies'
|
||||
|
||||
- script: |
|
||||
%PYTHON% -m pip install blurb
|
||||
%PYTHON% -m blurb merge -f Misc\NEWS
|
||||
displayName: 'Merge NEWS file'
|
||||
|
||||
- script: |
|
||||
%MSBUILD% Tools\msi\launcher\launcher.wixproj
|
||||
displayName: 'Build launcher installer'
|
||||
env:
|
||||
Platform: x86
|
||||
Py_OutDir: $(Build.BinariesDirectory)
|
||||
|
||||
- script: |
|
||||
%MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true
|
||||
%MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false
|
||||
displayName: 'Build win32 installer'
|
||||
env:
|
||||
Platform: x86
|
||||
Py_OutDir: $(Build.BinariesDirectory)
|
||||
PYTHON: $(Build.BinariesDirectory)\win32\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_win32
|
||||
BuildForRelease: true
|
||||
SuppressMinGWLib: true
|
||||
|
||||
- script: |
|
||||
%MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true
|
||||
%MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false
|
||||
displayName: 'Build amd64 installer'
|
||||
env:
|
||||
Platform: x64
|
||||
Py_OutDir: $(Build.BinariesDirectory)
|
||||
PYTHON: $(Build.BinariesDirectory)\amd64\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_amd64
|
||||
BuildForRelease: true
|
||||
SuppressMinGWLib: true
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Assemble artifact: msi (1/2)'
|
||||
inputs:
|
||||
sourceFolder: $(Build.BinariesDirectory)\win32\en-us
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\msi\win32
|
||||
contents: |
|
||||
*.msi
|
||||
*.cab
|
||||
*.exe
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Assemble artifact: msi (2/2)'
|
||||
inputs:
|
||||
sourceFolder: $(Build.BinariesDirectory)\amd64\en-us
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\msi\amd64
|
||||
contents: |
|
||||
*.msi
|
||||
*.cab
|
||||
*.exe
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish MSI'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\msi'
|
||||
artifactName: msi
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
jobs:
|
||||
- job: Build_Docs
|
||||
displayName: Docs build
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
#vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- script: Doc\make.bat html
|
||||
displayName: 'Build HTML docs'
|
||||
env:
|
||||
BUILDDIR: $(Build.BinariesDirectory)\Doc
|
||||
|
||||
- script: Doc\make.bat htmlhelp
|
||||
displayName: 'Build CHM docs'
|
||||
env:
|
||||
BUILDDIR: $(Build.BinariesDirectory)\Doc
|
||||
|
||||
#- powershell: |
|
||||
# mkdir -Force "$(Build.BinariesDirectory)\Doc\htmlhelp"
|
||||
# iwr "https://www.python.org/ftp/python/3.8.0/python380.chm" -OutFile "$(Build.BinariesDirectory)\Doc\htmlhelp\python390a0.chm"
|
||||
# displayName: 'Cheat at building CHM docs'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Assemble artifact: Doc'
|
||||
inputs:
|
||||
sourceFolder: $(Build.BinariesDirectory)\Doc
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\Doc
|
||||
contents: |
|
||||
html\**\*
|
||||
htmlhelp\*.chm
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish artifact: doc'
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)\Doc
|
||||
artifactName: doc
|
||||
|
||||
- job: Build_Python
|
||||
displayName: Python build
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Name: win32
|
||||
Arch: win32
|
||||
Platform: x86
|
||||
Configuration: Release
|
||||
_HostPython: .\python
|
||||
win32_d:
|
||||
Name: win32_d
|
||||
Arch: win32
|
||||
Platform: x86
|
||||
Configuration: Debug
|
||||
_HostPython: .\python
|
||||
amd64_d:
|
||||
Name: amd64_d
|
||||
Arch: amd64
|
||||
Platform: x64
|
||||
Configuration: Debug
|
||||
_HostPython: .\python
|
||||
arm64:
|
||||
Name: arm64
|
||||
Arch: arm64
|
||||
Platform: ARM64
|
||||
Configuration: Release
|
||||
_HostPython: python
|
||||
arm64_d:
|
||||
Name: arm64_d
|
||||
Arch: arm64
|
||||
Platform: ARM64
|
||||
Configuration: Debug
|
||||
_HostPython: python
|
||||
|
||||
steps:
|
||||
- template: ./build-steps.yml
|
||||
|
||||
- job: Build_Python_NonPGO
|
||||
displayName: Python non-PGO build
|
||||
condition: and(succeeded(), ne(variables['DoPGO'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
amd64:
|
||||
Name: amd64
|
||||
Arch: amd64
|
||||
Platform: x64
|
||||
Configuration: Release
|
||||
_HostPython: .\python
|
||||
|
||||
steps:
|
||||
- template: ./build-steps.yml
|
||||
|
||||
|
||||
- job: Build_Python_PGO
|
||||
displayName: Python PGO build
|
||||
condition: and(succeeded(), eq(variables['DoPGO'], 'true'))
|
||||
|
||||
# Allow up to five hours for PGO
|
||||
timeoutInMinutes: 300
|
||||
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
amd64:
|
||||
Name: amd64
|
||||
Arch: amd64
|
||||
Platform: x64
|
||||
Configuration: Release
|
||||
_HostPython: .\python
|
||||
|
||||
steps:
|
||||
- template: ./build-steps.yml
|
||||
parameters:
|
||||
ShouldPGO: true
|
||||
|
||||
|
||||
- job: TclTk_Lib
|
||||
displayName: Publish Tcl/Tk Library
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- script: PCbuild\get_externals.bat --no-openssl --no-libffi
|
||||
displayName: 'Get external dependencies'
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: 'Copy Tcl/Tk lib for publish'
|
||||
inputs:
|
||||
solution: PCbuild\tcltk.props
|
||||
platform: x86
|
||||
msbuildArguments: /t:CopyTclTkLib /p:OutDir="$(Build.ArtifactStagingDirectory)\tcl_win32"
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: 'Copy Tcl/Tk lib for publish'
|
||||
inputs:
|
||||
solution: PCbuild\tcltk.props
|
||||
platform: x64
|
||||
msbuildArguments: /t:CopyTclTkLib /p:OutDir="$(Build.ArtifactStagingDirectory)\tcl_amd64"
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish artifact: tcltk_lib_win32'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\tcl_win32'
|
||||
artifactName: tcltk_lib_win32
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish artifact: tcltk_lib_amd64'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\tcl_amd64'
|
||||
artifactName: tcltk_lib_amd64
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
jobs:
|
||||
- job: Make_Embed_Layout
|
||||
displayName: Make embeddable layout
|
||||
condition: and(succeeded(), eq(variables['DoEmbed'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Name: win32
|
||||
Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
amd64:
|
||||
Name: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
arm64:
|
||||
Name: arm64
|
||||
HostArch: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin_amd64\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_$(Name)'
|
||||
inputs:
|
||||
artifactName: bin_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- template: ./layout-command.yml
|
||||
|
||||
- powershell: |
|
||||
$d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }};
|
||||
Write-Host "##vso[task.setvariable variable=VersionText]$($d.PythonVersion)"
|
||||
displayName: 'Extract version numbers'
|
||||
|
||||
- powershell: >
|
||||
$(LayoutCmd)
|
||||
--copy "$(Build.ArtifactStagingDirectory)\layout"
|
||||
--zip "$(Build.ArtifactStagingDirectory)\embed\python-$(VersionText)-embed-$(Name).zip"
|
||||
--preset-embed
|
||||
displayName: 'Generate embeddable layout'
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Artifact: layout_embed_$(Name)'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\layout'
|
||||
artifactName: layout_embed_$(Name)
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: embed'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)\embed'
|
||||
ArtifactName: embed
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
jobs:
|
||||
- job: Make_Layouts
|
||||
displayName: Make layouts
|
||||
condition: and(succeeded(), eq(variables['DoLayout'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Name: win32
|
||||
Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8
|
||||
amd64:
|
||||
Name: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8
|
||||
arm64:
|
||||
Name: arm64
|
||||
HostArch: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin_amd64\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_$(Name)'
|
||||
inputs:
|
||||
artifactName: bin_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_$(Name)_d'
|
||||
inputs:
|
||||
artifactName: bin_$(Name)_d
|
||||
targetPath: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: doc'
|
||||
inputs:
|
||||
artifactName: doc
|
||||
targetPath: $(Build.BinariesDirectory)\doc
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: tcltk_lib_$(Name)'
|
||||
condition: and(succeeded(), variables['TclLibrary'])
|
||||
inputs:
|
||||
artifactName: tcltk_lib_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\tcltk_lib
|
||||
|
||||
- powershell: |
|
||||
copy "$(Build.BinariesDirectory)\bin\Activate.ps1" Lib\venv\scripts\common\Activate.ps1 -Force
|
||||
displayName: 'Copy signed files into sources'
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
- template: ./layout-command.yml
|
||||
|
||||
- powershell: |
|
||||
$(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\layout" --preset-default
|
||||
displayName: 'Generate full layout'
|
||||
env:
|
||||
TCL_LIBRARY: $(TclLibrary)
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Artifact: layout_full_$(Name)'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\layout'
|
||||
artifactName: layout_full_$(Name)
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
jobs:
|
||||
- job: Make_MSIX_Layout
|
||||
displayName: Make MSIX layout
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
#win32:
|
||||
# Name: win32
|
||||
# Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
# PYTHONHOME: $(Build.SourcesDirectory)
|
||||
# TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8
|
||||
amd64:
|
||||
Name: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8
|
||||
arm64:
|
||||
Name: arm64
|
||||
HostArch: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin_amd64\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_$(Name)'
|
||||
inputs:
|
||||
artifactName: bin_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_$(Name)_d'
|
||||
inputs:
|
||||
artifactName: bin_$(Name)_d
|
||||
targetPath: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: tcltk_lib_$(Name)'
|
||||
condition: and(succeeded(), variables['TclLibrary'])
|
||||
inputs:
|
||||
artifactName: tcltk_lib_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\tcltk_lib
|
||||
|
||||
- powershell: |
|
||||
copy "$(Build.BinariesDirectory)\bin\Activate.ps1" Lib\venv\scripts\common\Activate.ps1 -Force
|
||||
displayName: 'Copy signed files into sources'
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
- template: ./layout-command.yml
|
||||
|
||||
- powershell: |
|
||||
Remove-Item "$(Build.ArtifactStagingDirectory)\appx-store" -Recurse -Force -EA 0
|
||||
$(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\appx-store" --preset-appx --precompile
|
||||
displayName: 'Generate store APPX layout'
|
||||
env:
|
||||
TCL_LIBRARY: $(TclLibrary)
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Artifact: layout_appxstore_$(Name)'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\appx-store'
|
||||
artifactName: layout_appxstore_$(Name)
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: cert'
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
inputs:
|
||||
artifactName: cert
|
||||
targetPath: $(Build.BinariesDirectory)\cert
|
||||
|
||||
- powershell: |
|
||||
$info = (gc "$(Build.BinariesDirectory)\cert\certinfo.json" | ConvertFrom-JSON)
|
||||
Write-Host "Side-loadable APPX must be signed with '$($info.Subject)'"
|
||||
Write-Host "##vso[task.setvariable variable=APPX_DATA_PUBLISHER]$($info.Subject)"
|
||||
Write-Host "##vso[task.setvariable variable=APPX_DATA_SHA256]$($info.SHA256)"
|
||||
displayName: 'Override signing parameters'
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
- powershell: |
|
||||
Remove-Item "$(Build.ArtifactStagingDirectory)\appx" -Recurse -Force -EA 0
|
||||
$(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\appx" --preset-appx --precompile --include-symbols --include-tests
|
||||
displayName: 'Generate sideloading APPX layout'
|
||||
env:
|
||||
TCL_LIBRARY: $(TclLibrary)
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Artifact: layout_appx_$(Name)'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\appx'
|
||||
artifactName: layout_appx_$(Name)
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
jobs:
|
||||
- job: Make_Nuget_Layout
|
||||
displayName: Make Nuget layout
|
||||
condition: and(succeeded(), eq(variables['DoNuget'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Name: win32
|
||||
Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
amd64:
|
||||
Name: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
arm64:
|
||||
Name: arm64
|
||||
HostArch: amd64
|
||||
Python: $(Build.BinariesDirectory)\bin_amd64\python.exe
|
||||
PYTHONHOME: $(Build.SourcesDirectory)
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: bin_$(Name)'
|
||||
inputs:
|
||||
artifactName: bin_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- powershell: |
|
||||
copy $(Build.BinariesDirectory)\bin\Activate.ps1 Lib\venv\scripts\common\Activate.ps1 -Force
|
||||
displayName: 'Copy signed files into sources'
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
- template: ./layout-command.yml
|
||||
|
||||
- powershell: |
|
||||
$(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\nuget" --preset-nuget
|
||||
displayName: 'Generate nuget layout'
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Artifact: layout_nuget_$(Name)'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\nuget'
|
||||
artifactName: layout_nuget_$(Name)
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
jobs:
|
||||
- job: Make_MSI
|
||||
displayName: Make MSI
|
||||
condition: and(succeeded(), not(variables['SigningCertificate']))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
variables:
|
||||
ReleaseUri: http://www.python.org/{arch}
|
||||
DownloadUrl: https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi}
|
||||
Py_OutDir: $(Build.BinariesDirectory)
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: msi-steps.yml
|
||||
|
||||
- job: Make_Signed_MSI
|
||||
displayName: Make signed MSI
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
|
||||
variables:
|
||||
ReleaseUri: http://www.python.org/{arch}
|
||||
DownloadUrl: https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi}
|
||||
Py_OutDir: $(Build.BinariesDirectory)
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: msi-steps.yml
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
jobs:
|
||||
- job: Pack_MSIX
|
||||
displayName: Pack MSIX bundles
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
amd64:
|
||||
Name: amd64
|
||||
Artifact: appx
|
||||
Suffix:
|
||||
ShouldSign: true
|
||||
amd64_store:
|
||||
Name: amd64
|
||||
Artifact: appxstore
|
||||
Suffix: -store
|
||||
Upload: true
|
||||
arm64:
|
||||
Name: arm64
|
||||
Artifact: appx
|
||||
Suffix:
|
||||
ShouldSign: true
|
||||
arm64_store:
|
||||
Name: arm64
|
||||
Artifact: appxstore
|
||||
Suffix: -store
|
||||
Upload: true
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: layout_$(Artifact)_$(Name)'
|
||||
inputs:
|
||||
artifactName: layout_$(Artifact)_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\layout
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: symbols'
|
||||
inputs:
|
||||
artifactName: symbols
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
- powershell: |
|
||||
$d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }};
|
||||
Write-Host "##vso[task.setvariable variable=VersionText]$($d.PythonVersion)"
|
||||
Write-Host "##vso[task.setvariable variable=VersionNumber]$($d.PythonVersionNumber)"
|
||||
Write-Host "##vso[task.setvariable variable=VersionHex]$($d.PythonVersionHex)"
|
||||
Write-Host "##vso[task.setvariable variable=VersionUnique]$($d.PythonVersionUnique)"
|
||||
Write-Host "##vso[task.setvariable variable=Filename]python-$($d.PythonVersion)-$(Name)$(Suffix)"
|
||||
displayName: 'Extract version numbers'
|
||||
|
||||
- powershell: |
|
||||
./Tools/msi/make_appx.ps1 -layout "$(Build.BinariesDirectory)\layout" -msix "$(Build.ArtifactStagingDirectory)\msix\$(Filename).msix"
|
||||
displayName: 'Build msix'
|
||||
|
||||
- powershell: |
|
||||
7z a -tzip "$(Build.ArtifactStagingDirectory)\msix\$(Filename).appxsym" *.pdb
|
||||
displayName: 'Build appxsym'
|
||||
workingDirectory: $(Build.BinariesDirectory)\symbols\$(Name)
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: MSIX'
|
||||
condition: and(succeeded(), or(ne(variables['ShouldSign'], 'true'), not(variables['SigningCertificate'])))
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)\msix'
|
||||
ArtifactName: msix
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: MSIX'
|
||||
condition: and(succeeded(), and(eq(variables['ShouldSign'], 'true'), variables['SigningCertificate']))
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)\msix'
|
||||
ArtifactName: unsigned_msix
|
||||
|
||||
- powershell: |
|
||||
7z a -tzip "$(Build.ArtifactStagingDirectory)\msixupload\$(Filename).msixupload" *
|
||||
displayName: 'Build msixupload'
|
||||
condition: and(succeeded(), eq(variables['Upload'], 'true'))
|
||||
workingDirectory: $(Build.ArtifactStagingDirectory)\msix
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: MSIXUpload'
|
||||
condition: and(succeeded(), eq(variables['Upload'], 'true'))
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)\msixupload'
|
||||
ArtifactName: msixupload
|
||||
|
||||
|
||||
- job: Sign_MSIX
|
||||
displayName: Sign side-loadable MSIX bundles
|
||||
dependsOn:
|
||||
- Pack_MSIX
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
- template: ./find-sdk.yml
|
||||
|
||||
- powershell: |
|
||||
$d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }};
|
||||
Write-Host "##vso[task.setvariable variable=SigningDescription]Python $($d.PythonVersion)"
|
||||
displayName: 'Update signing description'
|
||||
condition: and(succeeded(), not(variables['SigningDescription']))
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download Artifact: unsigned_msix'
|
||||
inputs:
|
||||
artifactName: unsigned_msix
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
# MSIX must be signed and timestamped simultaneously
|
||||
- powershell: |
|
||||
$failed = $true
|
||||
foreach ($retry in 1..3) {
|
||||
signtool sign /a /n "$(SigningCertificate)" /fd sha256 /tr http://timestamp.digicert.com/ /td sha256 /d "$(SigningDescription)" (gi *.msix)
|
||||
if ($?) {
|
||||
$failed = $false
|
||||
break
|
||||
}
|
||||
sleep 1
|
||||
}
|
||||
if ($failed) {
|
||||
throw "Failed to sign MSIX"
|
||||
}
|
||||
displayName: 'Sign MSIX'
|
||||
workingDirectory: $(Build.BinariesDirectory)\unsigned_msix
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: MSIX'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.BinariesDirectory)\unsigned_msix'
|
||||
ArtifactName: msix
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
jobs:
|
||||
- job: Pack_Nuget
|
||||
displayName: Pack Nuget bundles
|
||||
condition: and(succeeded(), eq(variables['DoNuget'], 'true'))
|
||||
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
amd64:
|
||||
Name: amd64
|
||||
win32:
|
||||
Name: win32
|
||||
arm64:
|
||||
Name: arm64
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: layout_nuget_$(Name)'
|
||||
inputs:
|
||||
artifactName: layout_nuget_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\layout
|
||||
|
||||
- task: NugetToolInstaller@0
|
||||
displayName: 'Install Nuget'
|
||||
inputs:
|
||||
versionSpec: '>=5.0'
|
||||
|
||||
- powershell: |
|
||||
nuget pack "$(Build.BinariesDirectory)\layout\python.nuspec" -OutputDirectory $(Build.ArtifactStagingDirectory) -NoPackageAnalysis -NonInteractive
|
||||
displayName: 'Create nuget package'
|
||||
|
||||
- powershell: |
|
||||
gci *.nupkg | %{
|
||||
nuget sign "$_" -CertificateSubjectName "$(SigningCertificate)" -Timestamper http://timestamp.digicert.com/ -Overwrite
|
||||
}
|
||||
displayName: 'Sign nuget package'
|
||||
workingDirectory: $(Build.ArtifactStagingDirectory)
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: nuget'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
ArtifactName: nuget
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
jobs:
|
||||
- job: Publish_Nuget
|
||||
displayName: Publish Nuget packages
|
||||
condition: and(succeeded(), eq(variables['DoNuget'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: nuget'
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
inputs:
|
||||
artifactName: nuget
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: nuget'
|
||||
condition: and(succeeded(), variables['BuildToPublish'])
|
||||
inputs:
|
||||
artifactName: nuget
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
buildType: specific
|
||||
project: cpython
|
||||
pipeline: Windows-Release
|
||||
buildVersionToDownload: specific
|
||||
buildId: $(BuildToPublish)
|
||||
|
||||
- powershell: 'gci pythonarm*.nupkg | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del'
|
||||
displayName: 'Prevent publishing ARM/ARM64 packages'
|
||||
workingDirectory: '$(Build.BinariesDirectory)\nuget'
|
||||
condition: and(succeeded(), not(variables['PublishArmPackages']))
|
||||
|
||||
- task: NuGetCommand@2
|
||||
displayName: Push packages
|
||||
condition: and(succeeded(), eq(variables['SigningCertificate'], variables['__RealSigningCertificate']))
|
||||
inputs:
|
||||
command: push
|
||||
packagesToPush: '$(Build.BinariesDirectory)\nuget\*.nupkg'
|
||||
nuGetFeedType: external
|
||||
publishFeedCredentials: 'Python on Nuget'
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
jobs:
|
||||
- job: Publish_Python
|
||||
displayName: Publish python.org packages
|
||||
condition: and(succeeded(), and(eq(variables['DoMSI'], 'true'), eq(variables['DoEmbed'], 'true')))
|
||||
|
||||
pool:
|
||||
#vmImage: windows-2019
|
||||
name: 'Windows Release'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
|
||||
- task: UsePythonVersion@0
|
||||
displayName: 'Use Python 3.6 or later'
|
||||
inputs:
|
||||
versionSpec: '>=3.6'
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: Doc'
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
inputs:
|
||||
artifactName: Doc
|
||||
targetPath: $(Build.BinariesDirectory)\Doc
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: msi'
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
inputs:
|
||||
artifactName: msi
|
||||
targetPath: $(Build.BinariesDirectory)\msi
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: embed'
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
inputs:
|
||||
artifactName: embed
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact from $(BuildToPublish): Doc'
|
||||
condition: and(succeeded(), variables['BuildToPublish'])
|
||||
inputs:
|
||||
artifactName: Doc
|
||||
targetPath: $(Build.BinariesDirectory)\Doc
|
||||
buildType: specific
|
||||
project: cpython
|
||||
pipeline: 21
|
||||
buildVersionToDownload: specific
|
||||
buildId: $(BuildToPublish)
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact from $(BuildToPublish): msi'
|
||||
condition: and(succeeded(), variables['BuildToPublish'])
|
||||
inputs:
|
||||
artifactName: msi
|
||||
targetPath: $(Build.BinariesDirectory)\msi
|
||||
buildType: specific
|
||||
project: cpython
|
||||
pipeline: 21
|
||||
buildVersionToDownload: specific
|
||||
buildId: $(BuildToPublish)
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact from $(BuildToPublish): embed'
|
||||
condition: and(succeeded(), variables['BuildToPublish'])
|
||||
inputs:
|
||||
artifactName: embed
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
buildType: specific
|
||||
project: cpython
|
||||
pipeline: Windows-Release
|
||||
buildVersionToDownload: specific
|
||||
buildId: $(BuildToPublish)
|
||||
|
||||
- powershell: 'gci *embed-arm*.zip | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del'
|
||||
displayName: 'Prevent publishing ARM/ARM64 packages'
|
||||
workingDirectory: '$(Build.BinariesDirectory)\embed'
|
||||
condition: and(succeeded(), not(variables['PublishArmPackages']))
|
||||
|
||||
|
||||
- template: ./gpg-sign.yml
|
||||
parameters:
|
||||
GPGKeyFile: 'python-signing.key'
|
||||
Files: 'doc\htmlhelp\*.chm, msi\*\*, embed\*.zip'
|
||||
|
||||
- powershell: >
|
||||
$(Build.SourcesDirectory)\Tools\msi\uploadrelease.ps1
|
||||
-build msi
|
||||
-user $(PyDotOrgUsername)
|
||||
-server $(PyDotOrgServer)
|
||||
-doc_htmlhelp doc\htmlhelp
|
||||
-embed embed
|
||||
-skippurge
|
||||
-skiptest
|
||||
-skiphash
|
||||
condition: and(succeeded(), eq(variables['SigningCertificate'], variables['__RealSigningCertificate']))
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
displayName: 'Upload files to python.org'
|
||||
|
||||
- powershell: >
|
||||
python
|
||||
"$(Build.SourcesDirectory)\Tools\msi\purge.py"
|
||||
(gci msi\*\python-*.exe | %{ $_.Name -replace 'python-(.+?)(-|\.exe).+', '$1' } | select -First 1)
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
displayName: 'Purge CDN'
|
||||
|
||||
- powershell: |
|
||||
$failures = 0
|
||||
gci "msi\*\*-webinstall.exe" -File | %{
|
||||
$d = mkdir "tests\$($_.BaseName)" -Force
|
||||
gci $d -r -File | del
|
||||
$ic = copy $_ $d -PassThru
|
||||
"Checking layout for $($ic.Name)"
|
||||
Start-Process -wait $ic "/passive", "/layout", "$d\layout", "/log", "$d\log\install.log"
|
||||
if (-not $?) {
|
||||
Write-Error "Failed to validate layout of $($inst.Name)"
|
||||
$failures += 1
|
||||
}
|
||||
}
|
||||
if ($failures) {
|
||||
Write-Error "Failed to validate $failures installers"
|
||||
exit 1
|
||||
}
|
||||
#condition: and(succeeded(), eq(variables['SigningCertificate'], variables['__RealSigningCertificate']))
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
displayName: 'Test layouts'
|
||||
|
||||
- powershell: |
|
||||
$hashes = gci doc\htmlhelp\python*.chm, msi\*\*.exe, embed\*.zip | `
|
||||
Sort-Object Name | `
|
||||
Format-Table Name, @{
|
||||
Label="MD5";
|
||||
Expression={(Get-FileHash $_ -Algorithm MD5).Hash}
|
||||
}, Length -AutoSize | `
|
||||
Out-String -Width 4096
|
||||
$d = mkdir "$(Build.ArtifactStagingDirectory)\hashes" -Force
|
||||
$hashes | Out-File "$d\hashes.txt" -Encoding ascii
|
||||
$hashes
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
displayName: 'Generate hashes'
|
||||
|
||||
- powershell: |
|
||||
"Copying:"
|
||||
(gci msi\*\python*.asc, doc\htmlhelp\*.asc, embed\*.asc).FullName
|
||||
$d = mkdir "$(Build.ArtifactStagingDirectory)\hashes" -Force
|
||||
move msi\*\python*.asc, doc\htmlhelp\*.asc, embed\*.asc $d -Force
|
||||
gci msi -Directory | %{ move "msi\$_\*.asc" (mkdir "$d\$_" -Force) }
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
displayName: 'Copy GPG signatures for build'
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Artifact: hashes'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)\hashes'
|
||||
artifactName: hashes
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
jobs:
|
||||
- job: Publish_Store
|
||||
displayName: Publish Store packages
|
||||
condition: and(succeeded(), eq(variables['DoMSIX'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: msixupload'
|
||||
condition: and(succeeded(), not(variables['BuildToPublish']))
|
||||
inputs:
|
||||
artifactName: msixupload
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: msixupload'
|
||||
condition: and(succeeded(), variables['BuildToPublish'])
|
||||
inputs:
|
||||
artifactName: msixupload
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
buildType: specific
|
||||
project: cpython
|
||||
pipeline: Windows-Release
|
||||
buildVersionToDownload: specific
|
||||
buildId: $(BuildToPublish)
|
||||
|
||||
# TODO: eq(variables['SigningCertificate'], variables['__RealSigningCertificate'])
|
||||
# If we are not real-signed, DO NOT PUBLISH
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
parameters:
|
||||
Include: '*.exe, *.dll, *.pyd, *.cat, *.ps1'
|
||||
Exclude: 'vcruntime*, libffi*, libcrypto*, libssl*'
|
||||
|
||||
jobs:
|
||||
- job: Sign_Python
|
||||
displayName: Sign Python binaries
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Name: win32
|
||||
amd64:
|
||||
Name: amd64
|
||||
arm64:
|
||||
Name: arm64
|
||||
|
||||
steps:
|
||||
- template: ./checkout.yml
|
||||
- template: ./find-sdk.yml
|
||||
|
||||
- powershell: |
|
||||
$d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }};
|
||||
Write-Host "##vso[task.setvariable variable=SigningDescription]Python $($d.PythonVersion)"
|
||||
displayName: 'Update signing description'
|
||||
condition: and(succeeded(), not(variables['SigningDescription']))
|
||||
|
||||
- powershell: |
|
||||
Write-Host "##vso[build.addbuildtag]signed"
|
||||
displayName: 'Add build tags'
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: unsigned_bin_$(Name)'
|
||||
inputs:
|
||||
artifactName: unsigned_bin_$(Name)
|
||||
targetPath: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- powershell: |
|
||||
copy "$(Build.SourcesDirectory)\Lib\venv\scripts\common\Activate.ps1" .
|
||||
displayName: 'Copy files from source'
|
||||
workingDirectory: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- powershell: |
|
||||
$files = (gi ${{ parameters.Include }} -Exclude ${{ parameters.Exclude }})
|
||||
signtool sign /a /n "$(SigningCertificate)" /fd sha256 /d "$(SigningDescription)" $files
|
||||
displayName: 'Sign binaries'
|
||||
workingDirectory: $(Build.BinariesDirectory)\bin
|
||||
|
||||
- powershell: |
|
||||
$files = (gi ${{ parameters.Include }} -Exclude ${{ parameters.Exclude }})
|
||||
$failed = $true
|
||||
foreach ($retry in 1..10) {
|
||||
signtool timestamp /tr http://timestamp.digicert.com/ /td sha256 $files
|
||||
if ($?) {
|
||||
$failed = $false
|
||||
break
|
||||
}
|
||||
sleep 5
|
||||
}
|
||||
if ($failed) {
|
||||
Write-Host "##vso[task.logissue type=error]Failed to timestamp files"
|
||||
}
|
||||
displayName: 'Timestamp binaries'
|
||||
workingDirectory: $(Build.BinariesDirectory)\bin
|
||||
continueOnError: true
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish artifact: bin_$(Name)'
|
||||
inputs:
|
||||
targetPath: '$(Build.BinariesDirectory)\bin'
|
||||
artifactName: bin_$(Name)
|
||||
|
||||
|
||||
- job: Dump_CertInfo
|
||||
displayName: Capture certificate info
|
||||
condition: and(succeeded(), variables['SigningCertificate'])
|
||||
|
||||
pool:
|
||||
name: 'Windows Release'
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- powershell: |
|
||||
$m = 'CN=$(SigningCertificate)'
|
||||
$c = ((gci Cert:\CurrentUser\My), (gci Cert:\LocalMachine\My)) | %{ $_ } | `
|
||||
?{ $_.Subject -match $m } | `
|
||||
select -First 1
|
||||
if (-not $c) {
|
||||
Write-Host "Failed to find certificate for $(SigningCertificate)"
|
||||
exit
|
||||
}
|
||||
$d = mkdir "$(Build.BinariesDirectory)\tmp" -Force
|
||||
$cf = "$d\cert.cer"
|
||||
[IO.File]::WriteAllBytes($cf, $c.Export("Cer"))
|
||||
$csha = (certutil -dump $cf | sls "Cert Hash\(sha256\): (.+)").Matches.Groups[1].Value
|
||||
|
||||
$info = @{ Subject=$c.Subject; SHA256=$csha; }
|
||||
|
||||
$d = mkdir "$(Build.BinariesDirectory)\cert" -Force
|
||||
$info | ConvertTo-JSON -Compress | Out-File -Encoding utf8 "$d\certinfo.json"
|
||||
displayName: "Extract certificate info"
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish artifact: cert'
|
||||
inputs:
|
||||
targetPath: '$(Build.BinariesDirectory)\cert'
|
||||
artifactName: cert
|
||||
|
||||
|
||||
- job: Mark_Unsigned
|
||||
displayName: Tag unsigned build
|
||||
condition: and(succeeded(), not(variables['SigningCertificate']))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- powershell: |
|
||||
Write-Host "##vso[build.addbuildtag]unsigned"
|
||||
displayName: 'Add build tag'
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
jobs:
|
||||
- job: Test_Embed
|
||||
displayName: Test Embed
|
||||
condition: and(succeeded(), eq(variables['DoEmbed'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Name: win32
|
||||
amd64:
|
||||
Name: amd64
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: embed'
|
||||
inputs:
|
||||
artifactName: embed
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
- powershell: |
|
||||
$p = gi "$(Build.BinariesDirectory)\embed\python*embed-$(Name).zip"
|
||||
Expand-Archive -Path $p -DestinationPath "$(Build.BinariesDirectory)\Python"
|
||||
$p = gi "$(Build.BinariesDirectory)\Python\python.exe"
|
||||
Write-Host "##vso[task.prependpath]$(Split-Path -Parent $p)"
|
||||
displayName: 'Install Python and add to PATH'
|
||||
|
||||
- script: |
|
||||
python -c "import sys; print(sys.version)"
|
||||
displayName: 'Collect version number'
|
||||
|
||||
- script: |
|
||||
python -m site
|
||||
displayName: 'Collect site'
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
jobs:
|
||||
- job: Test_MSI
|
||||
displayName: Test MSI
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32_User:
|
||||
ExeMatch: 'python-[\dabrc.]+-webinstall\.exe'
|
||||
Logs: $(Build.ArtifactStagingDirectory)\logs\win32_User
|
||||
InstallAllUsers: 0
|
||||
win32_Machine:
|
||||
ExeMatch: 'python-[\dabrc.]+-webinstall\.exe'
|
||||
Logs: $(Build.ArtifactStagingDirectory)\logs\win32_Machine
|
||||
InstallAllUsers: 1
|
||||
amd64_User:
|
||||
ExeMatch: 'python-[\dabrc.]+-amd64-webinstall\.exe'
|
||||
Logs: $(Build.ArtifactStagingDirectory)\logs\amd64_User
|
||||
InstallAllUsers: 0
|
||||
amd64_Machine:
|
||||
ExeMatch: 'python-[\dabrc.]+-amd64-webinstall\.exe'
|
||||
Logs: $(Build.ArtifactStagingDirectory)\logs\amd64_Machine
|
||||
InstallAllUsers: 1
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadPipelineArtifact@1
|
||||
displayName: 'Download artifact: msi'
|
||||
inputs:
|
||||
artifactName: msi
|
||||
targetPath: $(Build.BinariesDirectory)\msi
|
||||
|
||||
- powershell: |
|
||||
$p = (gci -r *.exe | ?{ $_.Name -match '$(ExeMatch)' } | select -First 1)
|
||||
Write-Host "##vso[task.setvariable variable=SetupExe]$($p.FullName)"
|
||||
Write-Host "##vso[task.setvariable variable=SetupExeName]$($p.Name)"
|
||||
displayName: 'Find installer executable'
|
||||
workingDirectory: $(Build.BinariesDirectory)\msi
|
||||
|
||||
- script: >
|
||||
"$(SetupExe)"
|
||||
/passive
|
||||
/log "$(Logs)\install\log.txt"
|
||||
TargetDir="$(Build.BinariesDirectory)\Python"
|
||||
Include_debug=1
|
||||
Include_symbols=1
|
||||
InstallAllUsers=$(InstallAllUsers)
|
||||
displayName: 'Install Python'
|
||||
|
||||
- powershell: |
|
||||
$p = gi "$(Build.BinariesDirectory)\Python\python.exe"
|
||||
Write-Host "##vso[task.prependpath]$(Split-Path -Parent $p)"
|
||||
displayName: 'Add test Python to PATH'
|
||||
|
||||
- script: |
|
||||
python -c "import sys; print(sys.version)"
|
||||
displayName: 'Collect version number'
|
||||
|
||||
- script: |
|
||||
python -m site
|
||||
displayName: 'Collect site'
|
||||
|
||||
- powershell: |
|
||||
gci -r "${env:PROGRAMDATA}\Microsoft\Windows\Start Menu\Programs\Python*"
|
||||
displayName: 'Capture per-machine Start Menu items'
|
||||
- powershell: |
|
||||
gci -r "${env:APPDATA}\Microsoft\Windows\Start Menu\Programs\Python*"
|
||||
displayName: 'Capture per-user Start Menu items'
|
||||
|
||||
- powershell: |
|
||||
gci -r "HKLM:\Software\WOW6432Node\Python"
|
||||
displayName: 'Capture per-machine 32-bit registry'
|
||||
- powershell: |
|
||||
gci -r "HKLM:\Software\Python"
|
||||
displayName: 'Capture per-machine native registry'
|
||||
- powershell: |
|
||||
gci -r "HKCU:\Software\Python"
|
||||
displayName: 'Capture current-user registry'
|
||||
|
||||
- script: |
|
||||
python -m pip install "azure<0.10"
|
||||
python -m pip uninstall -y azure python-dateutil six
|
||||
displayName: 'Test (un)install package'
|
||||
|
||||
- script: |
|
||||
python -m test -uall -v test_ttk_guionly test_tk test_idle
|
||||
displayName: 'Test Tkinter and Idle'
|
||||
|
||||
- script: >
|
||||
"$(SetupExe)"
|
||||
/passive
|
||||
/uninstall
|
||||
/log "$(Logs)\uninstall\log.txt"
|
||||
displayName: 'Uninstall Python'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: logs'
|
||||
condition: true
|
||||
continueOnError: true
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)\logs'
|
||||
ArtifactName: msi_testlogs
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
jobs:
|
||||
- job: Test_Nuget
|
||||
displayName: Test Nuget
|
||||
condition: and(succeeded(), eq(variables['DoNuget'], 'true'))
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
win32:
|
||||
Package: pythonx86
|
||||
amd64:
|
||||
Package: python
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: 'Download artifact: nuget'
|
||||
inputs:
|
||||
artifactName: nuget
|
||||
downloadPath: $(Build.BinariesDirectory)
|
||||
|
||||
- task: NugetToolInstaller@0
|
||||
inputs:
|
||||
versionSpec: '>= 5'
|
||||
|
||||
- powershell: >
|
||||
nuget install
|
||||
$(Package)
|
||||
-Source "$(Build.BinariesDirectory)\nuget"
|
||||
-OutputDirectory "$(Build.BinariesDirectory)\install"
|
||||
-Prerelease
|
||||
-ExcludeVersion
|
||||
-NonInteractive
|
||||
displayName: 'Install Python'
|
||||
|
||||
- powershell: |
|
||||
$p = gi "$(Build.BinariesDirectory)\install\$(Package)\tools\python.exe"
|
||||
Write-Host "##vso[task.prependpath]$(Split-Path -Parent $p)"
|
||||
displayName: 'Add test Python to PATH'
|
||||
|
||||
- script: |
|
||||
python -c "import sys; print(sys.version)"
|
||||
displayName: 'Collect version number'
|
||||
|
||||
- script: |
|
||||
python -m site
|
||||
displayName: 'Collect site'
|
||||
|
||||
- script: |
|
||||
python -m pip install "azure<0.10"
|
||||
python -m pip uninstall -y azure python-dateutil six
|
||||
displayName: 'Test (un)install package'
|
||||
88
.gitattributes
vendored
88
.gitattributes
vendored
|
|
@ -22,44 +22,27 @@ Lib/test/sndhdrdata/sndhdr.* binary
|
|||
PC/classicAppCompat.* binary
|
||||
|
||||
# Text files that should not be subject to eol conversion
|
||||
Lib/test/cjkencodings/* -text
|
||||
Lib/test/decimaltestdata/*.decTest -text
|
||||
Lib/test/test_email/data/*.txt -text
|
||||
Lib/test/xmltestdata/* -text
|
||||
Lib/test/coding20731.py -text
|
||||
Lib/test/test_importlib/data01/* -text
|
||||
Lib/test/test_importlib/namespacedata01/* -text
|
||||
[attr]noeol -text
|
||||
|
||||
Lib/test/cjkencodings/* noeol
|
||||
Lib/test/coding20731.py noeol
|
||||
Lib/test/decimaltestdata/*.decTest noeol
|
||||
Lib/test/test_email/data/*.txt noeol
|
||||
Lib/test/test_importlib/resources/data01/* noeol
|
||||
Lib/test/test_importlib/resources/namespacedata01/* noeol
|
||||
Lib/test/xmltestdata/* noeol
|
||||
|
||||
# CRLF files
|
||||
*.bat text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
*.sln text eol=crlf
|
||||
*.vcxproj* text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.proj text eol=crlf
|
||||
PCbuild/readme.txt text eol=crlf
|
||||
PC/readme.txt text eol=crlf
|
||||
[attr]dos text eol=crlf
|
||||
|
||||
# Generated files
|
||||
# https://github.com/github/linguist#generated-code
|
||||
Modules/clinic/*.h linguist-generated=true
|
||||
Objects/clinic/*.h linguist-generated=true
|
||||
PC/clinic/*.h linguist-generated=true
|
||||
Python/clinic/*.h linguist-generated=true
|
||||
Python/deepfreeze/*.c linguist-generated=true
|
||||
Python/frozen_modules/*.h linguist-generated=true
|
||||
Python/frozen_modules/MANIFEST linguist-generated=true
|
||||
Include/internal/pycore_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
|
||||
*_db.h linguist-generated=true
|
||||
Doc/library/token-list.inc linguist-generated=true
|
||||
Include/token.h linguist-generated=true
|
||||
Lib/token.py linguist-generated=true
|
||||
Parser/token.c linguist-generated=true
|
||||
Programs/test_frozenmain.h linguist-generated=true
|
||||
*.bat dos
|
||||
*.proj dos
|
||||
*.props dos
|
||||
*.ps1 dos
|
||||
*.sln dos
|
||||
*.vcxproj* dos
|
||||
PC/readme.txt dos
|
||||
PCbuild/readme.txt dos
|
||||
|
||||
# Language aware diff headers
|
||||
# https://tekin.co.uk/2020/10/better-git-diff-output-for-ruby-python-elixir-and-more
|
||||
|
|
@ -70,3 +53,38 @@ Programs/test_frozenmain.h linguist-generated=true
|
|||
*.html diff=html
|
||||
*.py diff=python
|
||||
*.md diff=markdown
|
||||
|
||||
# Generated files
|
||||
# https://github.com/github/linguist/blob/master/docs/overrides.md
|
||||
#
|
||||
# To always hide generated files in local diffs, mark them as binary:
|
||||
# $ git config diff.generated.binary true
|
||||
#
|
||||
[attr]generated linguist-generated=true diff=generated
|
||||
|
||||
**/clinic/*.c.h generated
|
||||
*_db.h generated
|
||||
Doc/data/stable_abi.dat generated
|
||||
Doc/library/token-list.inc generated
|
||||
Include/internal/pycore_ast.h generated
|
||||
Include/internal/pycore_ast_state.h generated
|
||||
Include/internal/pycore_opcode.h generated
|
||||
Include/internal/pycore_*_generated.h generated
|
||||
Include/opcode.h generated
|
||||
Include/token.h generated
|
||||
Lib/keyword.py generated
|
||||
Lib/test/levenshtein_examples.json generated
|
||||
Lib/test/test_stable_abi_ctypes.py generated
|
||||
Lib/token.py generated
|
||||
Objects/typeslots.inc generated
|
||||
PC/python3dll.c generated
|
||||
Parser/parser.c generated
|
||||
Parser/token.c generated
|
||||
Programs/test_frozenmain.h generated
|
||||
Python/Python-ast.c generated
|
||||
Python/generated_cases.c.h generated
|
||||
Python/opcode_targets.h generated
|
||||
Python/stdlib_module_names.h generated
|
||||
Tools/peg_generator/pegen/grammar_parser.py generated
|
||||
aclocal.m4 generated
|
||||
configure generated
|
||||
|
|
|
|||
64
.github/CODEOWNERS
vendored
64
.github/CODEOWNERS
vendored
|
|
@ -4,12 +4,18 @@
|
|||
# It uses the same pattern rule for gitignore file
|
||||
# https://git-scm.com/docs/gitignore#_pattern_format
|
||||
|
||||
# GitHub
|
||||
.github/** @ezio-melotti
|
||||
|
||||
# Build system
|
||||
configure* @erlend-aasland @corona10
|
||||
|
||||
# asyncio
|
||||
**/*asyncio* @1st1 @asvetlov
|
||||
**/*asyncio* @1st1 @asvetlov @gvanrossum @kumaraditya303
|
||||
|
||||
# Core
|
||||
**/*context* @1st1
|
||||
**/*genobject* @1st1 @markshannon
|
||||
**/*genobject* @markshannon
|
||||
**/*hamt* @1st1
|
||||
Objects/set* @rhettinger
|
||||
Objects/dict* @methane @markshannon
|
||||
|
|
@ -18,17 +24,26 @@ Objects/codeobject.c @markshannon
|
|||
Objects/frameobject.c @markshannon
|
||||
Objects/call.c @markshannon
|
||||
Python/ceval.c @markshannon
|
||||
Python/compile.c @markshannon
|
||||
Python/compile.c @markshannon @iritkatriel
|
||||
Python/ast_opt.c @isidentical
|
||||
Lib/test/test_patma.py @brandtbucher
|
||||
Lib/test/test_peepholer.py @brandtbucher
|
||||
|
||||
# Exceptions
|
||||
Lib/traceback.py @iritkatriel
|
||||
Lib/test/test_except*.py @iritkatriel
|
||||
Lib/test/test_traceback.py @iritkatriel
|
||||
Objects/exceptions.c @iritkatriel
|
||||
Python/traceback.c @iritkatriel
|
||||
|
||||
# Hashing
|
||||
**/*hashlib* @python/crypto-team @tiran
|
||||
**/*pyhash* @python/crypto-team @tiran
|
||||
**/*sha* @python/crypto-team @tiran
|
||||
**/*md5* @python/crypto-team @tiran
|
||||
**/*blake* @python/crypto-team @tiran
|
||||
/Modules/_blake2/** @python/crypto-team @tiran
|
||||
/Modules/_sha3/** @python/crypto-team @tiran
|
||||
**/*hashlib* @tiran
|
||||
**/*pyhash* @tiran
|
||||
**/*sha* @tiran
|
||||
**/*md5* @tiran
|
||||
**/*blake* @tiran
|
||||
/Modules/_blake2/** @tiran
|
||||
/Modules/_sha3/** @tiran
|
||||
|
||||
# logging
|
||||
**/*logging* @vsajip
|
||||
|
|
@ -43,6 +58,7 @@ Python/ast_opt.c @isidentical
|
|||
/Lib/html/ @ezio-melotti
|
||||
/Lib/_markupbase.py @ezio-melotti
|
||||
/Lib/test/test_html*.py @ezio-melotti
|
||||
/Tools/build/parse_html5_entities.py @ezio-melotti
|
||||
|
||||
# Import (including importlib).
|
||||
# Ignoring importlib.h so as to not get flagged on
|
||||
|
|
@ -50,14 +66,8 @@ Python/ast_opt.c @isidentical
|
|||
# bytecode.
|
||||
**/*import*.c @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw
|
||||
**/*import*.py @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw
|
||||
|
||||
|
||||
# SSL
|
||||
**/*ssl* @python/crypto-team
|
||||
**/*.pem @python/crypto-team
|
||||
|
||||
# CSPRNG
|
||||
Python/bootstrap_hash.c @python/crypto-team
|
||||
**/*importlib/resources/* @jaraco @warsaw @FFY00
|
||||
**/importlib/metadata/* @jaraco @warsaw
|
||||
|
||||
# Dates and times
|
||||
**/*datetime* @pganssle @abalkin
|
||||
|
|
@ -93,10 +103,10 @@ Lib/ast.py @isidentical
|
|||
|
||||
# Mock
|
||||
/Lib/unittest/mock.py @cjw296
|
||||
/Lib/unittest/test/testmock/* @cjw296
|
||||
/Lib/test/test_unittest/testmock/* @cjw296
|
||||
|
||||
# SQLite 3
|
||||
**/*sqlite* @berkerpeksag
|
||||
**/*sqlite* @berkerpeksag @erlend-aasland
|
||||
|
||||
# subprocess
|
||||
/Lib/subprocess.py @gpshead
|
||||
|
|
@ -122,13 +132,13 @@ Lib/ast.py @isidentical
|
|||
**/*bisect* @rhettinger
|
||||
**/*heapq* @rhettinger
|
||||
**/*functools* @rhettinger
|
||||
**/*decimal* @rhettinger @skrah
|
||||
**/*decimal* @rhettinger
|
||||
|
||||
**/*dataclasses* @ericvsmith
|
||||
|
||||
**/*idlelib* @terryjreedy
|
||||
|
||||
**/*typing* @gvanrossum @Fidget-Spinner
|
||||
**/*typing* @gvanrossum @Fidget-Spinner @JelleZijlstra @AlexWaygood
|
||||
|
||||
**/*ftplib @giampaolo
|
||||
**/*shutil @giampaolo
|
||||
|
|
@ -137,6 +147,16 @@ Lib/ast.py @isidentical
|
|||
**/*cgi* @ethanfurman
|
||||
**/*tarfile* @ethanfurman
|
||||
|
||||
**/*tomllib* @encukou @hauntsaninja
|
||||
|
||||
**/*sysconfig* @FFY00
|
||||
|
||||
# macOS
|
||||
/Mac/ @python/macos-team
|
||||
**/*osx_support* @python/macos-team
|
||||
|
||||
# pathlib
|
||||
**/*pathlib* @barneygale
|
||||
|
||||
# zipfile.Path
|
||||
**/*zipfile/*_path.py @jaraco
|
||||
|
|
|
|||
20
.github/CONTRIBUTING.rst
vendored
20
.github/CONTRIBUTING.rst
vendored
|
|
@ -4,21 +4,9 @@ Contributing to Python
|
|||
Build Status
|
||||
------------
|
||||
|
||||
- main
|
||||
- `Buildbot status overview <https://buildbot.python.org/all/#/release_status>`_
|
||||
|
||||
+ `Stable buildbots <http://buildbot.python.org/3.x.stable/>`_
|
||||
|
||||
- 3.9
|
||||
|
||||
+ `Stable buildbots <http://buildbot.python.org/3.9.stable/>`_
|
||||
|
||||
- 3.8
|
||||
|
||||
+ `Stable buildbots <http://buildbot.python.org/3.8.stable/>`_
|
||||
|
||||
- 3.7
|
||||
|
||||
+ `Stable buildbots <http://buildbot.python.org/3.7.stable/>`_
|
||||
- `GitHub Actions status <https://github.com/python/cpython/actions/workflows/build.yml>`_
|
||||
|
||||
|
||||
Thank You
|
||||
|
|
@ -38,13 +26,13 @@ also suggestions on how you can most effectively help the project.
|
|||
|
||||
Please be aware that our workflow does deviate slightly from the typical GitHub
|
||||
project. Details on how to properly submit a pull request are covered in
|
||||
`Lifecycle of a Pull Request <https://devguide.python.org/pullrequest/>`_.
|
||||
`Lifecycle of a Pull Request <https://devguide.python.org/getting-started/pull-request-lifecycle.html>`_.
|
||||
We utilize various bots and status checks to help with this, so do follow the
|
||||
comments they leave and their "Details" links, respectively. The key points of
|
||||
our workflow that are not covered by a bot or status check are:
|
||||
|
||||
- All discussions that are not directly related to the code in the pull request
|
||||
should happen on bugs.python.org
|
||||
should happen on `GitHub Issues <https://github.com/python/cpython/issues>`_.
|
||||
- Upon your first non-trivial pull request (which includes documentation changes),
|
||||
feel free to add yourself to ``Misc/ACKS``
|
||||
|
||||
|
|
|
|||
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
|
|
@ -1,2 +0,0 @@
|
|||
custom: https://www.python.org/psf/donations/python-dev/
|
||||
github: [python]
|
||||
32
.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Submit a bug report
|
||||
labels: "type-bug"
|
||||
---
|
||||
|
||||
<!--
|
||||
If you're new to Python and you're not sure whether what you're experiencing is a bug, the CPython issue tracker is not
|
||||
the right place to seek help. Consider the following options instead:
|
||||
|
||||
- reading the Python tutorial: https://docs.python.org/3/tutorial/
|
||||
- posting in the "Users" category on discuss.python.org: https://discuss.python.org/c/users/7
|
||||
- emailing the Python-list mailing list: https://mail.python.org/mailman/listinfo/python-list
|
||||
- searching our issue tracker (https://github.com/python/cpython/issues) to see if
|
||||
your problem has already been reported
|
||||
-->
|
||||
|
||||
# Bug report
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
Include a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example), if possible.
|
||||
|
||||
# Your environment
|
||||
|
||||
<!-- Include as many relevant details as possible about the environment you experienced the bug in -->
|
||||
|
||||
- CPython versions tested on:
|
||||
- Operating system and architecture:
|
||||
|
||||
<!--
|
||||
You can freely edit this text. Remove any lines you believe are unnecessary.
|
||||
-->
|
||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
7
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
contact_links:
|
||||
- name: "Getting help"
|
||||
about: "Ask questions about using Python and debugging errors on Discourse."
|
||||
url: "https://discuss.python.org/c/users/7"
|
||||
- name: "Proposing new features"
|
||||
about: "Submit major feature proposal (e.g. syntax changes) to an ideas forum first."
|
||||
url: "https://discuss.python.org/c/ideas/6"
|
||||
33
.github/ISSUE_TEMPLATE/crash.md
vendored
Normal file
33
.github/ISSUE_TEMPLATE/crash.md
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
name: Crash report
|
||||
about: A hard crash of the interpreter, possibly with a core dump
|
||||
labels: "type-crash"
|
||||
---
|
||||
|
||||
<!--
|
||||
Use this template for hard crashes of the interpreter, segmentation faults, failed C-level assertions, and similar.
|
||||
Do not submit this form if you encounter an exception being unexpectedly raised from a Python function.
|
||||
Most of the time, these should be filed as bugs, rather than crashes.
|
||||
|
||||
The CPython interpreter is itself written in a different programming language, C.
|
||||
For CPython, a "crash" is when Python itself fails, leading to a traceback in the C stack.
|
||||
-->
|
||||
|
||||
# Crash report
|
||||
|
||||
Tell us what happened, ideally including a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example).
|
||||
|
||||
# Error messages
|
||||
|
||||
Enter any relevant error message caused by the crash, including a core dump if there is one.
|
||||
|
||||
# Your environment
|
||||
|
||||
<!-- Include as many relevant details as possible about the environment you experienced the bug in -->
|
||||
|
||||
- CPython versions tested on:
|
||||
- Operating system and architecture:
|
||||
|
||||
<!--
|
||||
You can freely edit this text. Remove any lines you believe are unnecessary.
|
||||
-->
|
||||
9
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
9
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: Documentation
|
||||
about: Report a problem with the documentation
|
||||
labels: "docs"
|
||||
---
|
||||
|
||||
# Documentation
|
||||
|
||||
(A clear and concise description of the issue.)
|
||||
28
.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
name: Feature or enhancement
|
||||
about: Submit a proposal for a new CPython feature or enhancement
|
||||
labels: "type-feature"
|
||||
---
|
||||
|
||||
# Feature or enhancement
|
||||
|
||||
(A clear and concise description of your proposal.)
|
||||
|
||||
# Pitch
|
||||
|
||||
(Explain why this feature or enhancement should be implemented and how it would be used.
|
||||
Add examples, if applicable.)
|
||||
|
||||
# Previous discussion
|
||||
|
||||
<!--
|
||||
New features to Python should first be discussed elsewhere before creating issues on GitHub,
|
||||
for example in the "ideas" category (https://discuss.python.org/c/ideas/6) of discuss.python.org,
|
||||
or the python-ideas mailing list (https://mail.python.org/mailman3/lists/python-ideas.python.org/).
|
||||
Use this space to post links to the places where you have already discussed this feature proposal:
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
You can freely edit this text. Remove any lines you believe are unnecessary.
|
||||
-->
|
||||
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -7,10 +7,10 @@ Please read this comment in its entirety. It's quite important.
|
|||
It should be in the following format:
|
||||
|
||||
```
|
||||
bpo-NNNN: Summary of the changes made
|
||||
gh-NNNNN: Summary of the changes made
|
||||
```
|
||||
|
||||
Where: bpo-NNNN refers to the issue number in the https://bugs.python.org.
|
||||
Where: gh-NNNNN refers to the GitHub issue number.
|
||||
|
||||
Most PRs will require an issue number. Trivial changes, like fixing a typo, do not need an issue.
|
||||
|
||||
|
|
|
|||
2
.github/SECURITY.md
vendored
2
.github/SECURITY.md
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
The Python team applies security fixes according to the table
|
||||
in [the devguide](
|
||||
https://devguide.python.org/#status-of-python-branches
|
||||
https://devguide.python.org/versions/#supported-versions
|
||||
).
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
|
|
|||
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
|
|
@ -7,3 +7,8 @@ updates:
|
|||
labels:
|
||||
- "skip issue"
|
||||
- "skip news"
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
update-types:
|
||||
- "version-update:semver-minor"
|
||||
- "version-update:semver-patch"
|
||||
|
|
|
|||
125
.github/workflows/build.yml
vendored
125
.github/workflows/build.yml
vendored
|
|
@ -1,6 +1,6 @@
|
|||
name: Tests
|
||||
|
||||
# bpo-40548: "paths-ignore" is not used to skip documentation-only PRs, because
|
||||
# gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because
|
||||
# it prevents to mark a job as mandatory. A PR cannot be merged if a job is
|
||||
# mandatory but not scheduled because of "paths-ignore".
|
||||
on:
|
||||
|
|
@ -8,6 +8,7 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- '3.11'
|
||||
- '3.10'
|
||||
- '3.9'
|
||||
- '3.8'
|
||||
|
|
@ -15,26 +16,32 @@ on:
|
|||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
- '3.11'
|
||||
- '3.10'
|
||||
- '3.9'
|
||||
- '3.8'
|
||||
- '3.7'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check_source:
|
||||
name: 'Check for source changes'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
run_tests: ${{ steps.check.outputs.run_tests }}
|
||||
run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Check for source changes
|
||||
id: check
|
||||
run: |
|
||||
if [ -z "$GITHUB_BASE_REF" ]; then
|
||||
echo '::set-output name=run_tests::true'
|
||||
echo '::set-output name=run_ssl_tests::true'
|
||||
echo "run_tests=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
git fetch origin $GITHUB_BASE_REF --depth=1
|
||||
# git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
|
||||
|
|
@ -50,8 +57,7 @@ jobs:
|
|||
# into the PR branch anyway.
|
||||
#
|
||||
# https://github.com/python/core-workflow/issues/373
|
||||
git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo '::set-output name=run_tests::true' || true
|
||||
git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo '::set-output name=run_ssl_tests::true' || true
|
||||
git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true
|
||||
fi
|
||||
|
||||
check_generated_files:
|
||||
|
|
@ -60,14 +66,31 @@ jobs:
|
|||
needs: check_source
|
||||
if: needs.check_source.outputs.run_tests == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
- name: Install Dependencies
|
||||
run: sudo ./.github/workflows/posix-deps-apt.sh
|
||||
- name: Build CPython
|
||||
- name: Add ccache to PATH
|
||||
run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
||||
- name: Configure ccache action
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: Check Autoconf version 2.69 and aclocal 1.16.3
|
||||
run: |
|
||||
grep "Generated by GNU Autoconf 2.69" configure
|
||||
grep "aclocal 1.16.3" aclocal.m4
|
||||
grep -q "runstatedir" configure
|
||||
grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4
|
||||
- name: Configure CPython
|
||||
run: |
|
||||
# Build Python with the libpython dynamic library
|
||||
./configure --with-pydebug --enable-shared
|
||||
- name: Regenerate autoconf files with container image
|
||||
run: make regen-configure
|
||||
- name: Build CPython
|
||||
run: |
|
||||
# Deepfreeze will usually cause global objects to be added or removed,
|
||||
# so we run it before regen-global-objects gets rum (in regen-all).
|
||||
make regen-deepfreeze
|
||||
make -j4 regen-all
|
||||
make regen-stdlib-module-names
|
||||
- name: Check for changes
|
||||
|
|
@ -75,50 +98,55 @@ jobs:
|
|||
git add -u
|
||||
changes=$(git status --porcelain)
|
||||
# Check for changes in regenerated files
|
||||
if ! test -z "$changes"
|
||||
then
|
||||
echo "Generated files not up to date. Perhaps you forgot to run make regen-all or build.bat --regen ;)"
|
||||
if test -n "$changes"; then
|
||||
echo "Generated files not up to date."
|
||||
echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)"
|
||||
echo "configure files must be regenerated with a specific version of autoconf."
|
||||
echo "$changes"
|
||||
echo ""
|
||||
git diff --staged || true
|
||||
exit 1
|
||||
fi
|
||||
- name: Check exported libpython symbols
|
||||
run: make smelly
|
||||
- name: Check limited ABI symbols
|
||||
run: make check-limited-abi
|
||||
- name: Check Autoconf version 2.69
|
||||
run: |
|
||||
grep "Generated by GNU Autoconf 2.69" configure
|
||||
grep "PKG_PROG_PKG_CONFIG" aclocal.m4
|
||||
|
||||
build_win32:
|
||||
name: 'Windows (x86)'
|
||||
runs-on: windows-latest
|
||||
needs: check_source
|
||||
if: needs.check_source.outputs.run_tests == 'true'
|
||||
env:
|
||||
IncludeUwp: 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build CPython
|
||||
run: .\PCbuild\build.bat -e -p Win32
|
||||
run: .\PCbuild\build.bat -e -d -p Win32
|
||||
timeout-minutes: 30
|
||||
- name: Display build info
|
||||
run: .\python.bat -m test.pythoninfo
|
||||
- name: Tests
|
||||
run: .\PCbuild\rt.bat -p Win32 -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
|
||||
run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
|
||||
|
||||
build_win_amd64:
|
||||
name: 'Windows (x64)'
|
||||
runs-on: windows-latest
|
||||
needs: check_source
|
||||
if: needs.check_source.outputs.run_tests == 'true'
|
||||
env:
|
||||
IncludeUwp: 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Register MSVC problem matcher
|
||||
run: echo "::add-matcher::.github/problem-matchers/msvc.json"
|
||||
- name: Build CPython
|
||||
run: .\PCbuild\build.bat -e -p x64
|
||||
run: .\PCbuild\build.bat -e -d -p x64
|
||||
timeout-minutes: 30
|
||||
- name: Display build info
|
||||
run: .\python.bat -m test.pythoninfo
|
||||
- name: Tests
|
||||
run: .\PCbuild\rt.bat -p x64 -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
|
||||
run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
|
||||
|
||||
build_macos:
|
||||
name: 'macOS'
|
||||
|
|
@ -128,7 +156,7 @@ jobs:
|
|||
env:
|
||||
PYTHONSTRICTEXTENSIONBUILD: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Prepare homebrew environment variables
|
||||
run: |
|
||||
echo "LDFLAGS=-L$(brew --prefix tcl-tk)/lib" >> $GITHUB_ENV
|
||||
|
|
@ -148,10 +176,10 @@ jobs:
|
|||
needs: check_source
|
||||
if: needs.check_source.outputs.run_tests == 'true'
|
||||
env:
|
||||
OPENSSL_VER: 1.1.1l
|
||||
OPENSSL_VER: 1.1.1s
|
||||
PYTHONSTRICTEXTENSIONBUILD: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Register gcc problem matcher
|
||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||
- name: Install Dependencies
|
||||
|
|
@ -163,7 +191,7 @@ jobs:
|
|||
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
|
||||
- name: 'Restore OpenSSL build'
|
||||
id: cache-openssl
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
|
||||
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
|
||||
|
|
@ -174,32 +202,47 @@ jobs:
|
|||
run: |
|
||||
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
||||
- name: Configure ccache action
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
- name: Configure CPython
|
||||
run: ./configure --with-pydebug --with-openssl=$OPENSSL_DIR
|
||||
- name: Build CPython
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: Setup directory envs for out-of-tree builds
|
||||
run: |
|
||||
echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV
|
||||
echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV
|
||||
- name: Create directories for read-only out-of-tree builds
|
||||
run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR
|
||||
- name: Bind mount sources read-only
|
||||
run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR
|
||||
- name: Configure CPython out-of-tree
|
||||
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
||||
run: ../cpython-ro-srcdir/configure --with-pydebug --with-openssl=$OPENSSL_DIR
|
||||
- name: Build CPython out-of-tree
|
||||
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
||||
run: make -j4
|
||||
- name: Display build info
|
||||
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
||||
run: make pythoninfo
|
||||
- name: Remount sources writable for tests
|
||||
# some tests write to srcdir, lack of pyc files slows down testing
|
||||
run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw
|
||||
- name: Tests
|
||||
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
||||
run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
|
||||
|
||||
build_ubuntu_ssltests:
|
||||
name: 'Ubuntu SSL tests with OpenSSL'
|
||||
runs-on: ubuntu-20.04
|
||||
needs: check_source
|
||||
if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true'
|
||||
if: needs.check_source.outputs.run_tests == 'true'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
openssl_ver: [1.1.1l, 3.0.0]
|
||||
openssl_ver: [1.1.1s, 3.0.7, 3.1.0-beta1]
|
||||
env:
|
||||
OPENSSL_VER: ${{ matrix.openssl_ver }}
|
||||
MULTISSL_DIR: ${{ github.workspace }}/multissl
|
||||
OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}
|
||||
LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Register gcc problem matcher
|
||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||
- name: Install Dependencies
|
||||
|
|
@ -211,7 +254,7 @@ jobs:
|
|||
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
|
||||
- name: 'Restore OpenSSL build'
|
||||
id: cache-openssl
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
|
||||
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
|
||||
|
|
@ -222,7 +265,7 @@ jobs:
|
|||
run: |
|
||||
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
||||
- name: Configure ccache action
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: Configure CPython
|
||||
run: ./configure --with-pydebug --with-openssl=$OPENSSL_DIR
|
||||
- name: Build CPython
|
||||
|
|
@ -239,11 +282,11 @@ jobs:
|
|||
needs: check_source
|
||||
if: needs.check_source.outputs.run_tests == 'true'
|
||||
env:
|
||||
OPENSSL_VER: 1.1.1l
|
||||
OPENSSL_VER: 1.1.1s
|
||||
PYTHONSTRICTEXTENSIONBUILD: 1
|
||||
ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Register gcc problem matcher
|
||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||
- name: Install Dependencies
|
||||
|
|
@ -255,7 +298,7 @@ jobs:
|
|||
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
|
||||
- name: 'Restore OpenSSL build'
|
||||
id: cache-openssl
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
|
||||
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
|
||||
|
|
@ -266,7 +309,7 @@ jobs:
|
|||
run: |
|
||||
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
||||
- name: Configure ccache action
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: Configure CPython
|
||||
run: ./configure --with-address-sanitizer --without-pymalloc
|
||||
- name: Build CPython
|
||||
|
|
@ -274,4 +317,4 @@ jobs:
|
|||
- name: Display build info
|
||||
run: make pythoninfo
|
||||
- name: Tests
|
||||
run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu -x test_ctypes test_crypt test_decimal test_faulthandler test_interpreters test___all__ test_idle test_tix test_tk test_ttk_guionly test_ttk_textonly test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_spawn"
|
||||
run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
|
||||
|
|
|
|||
36
.github/workflows/build_msi.yml
vendored
36
.github/workflows/build_msi.yml
vendored
|
|
@ -5,35 +5,31 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- '3.10'
|
||||
- '3.9'
|
||||
- '3.8'
|
||||
- '3.7'
|
||||
- '3.*'
|
||||
paths:
|
||||
- 'Tools/msi/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
- '3.10'
|
||||
- '3.9'
|
||||
- '3.8'
|
||||
- '3.7'
|
||||
- '3.*'
|
||||
paths:
|
||||
- 'Tools/msi/**'
|
||||
|
||||
jobs:
|
||||
build_win32:
|
||||
name: 'Windows (x86) Installer'
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build CPython installer
|
||||
run: .\Tools\msi\build.bat -x86
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
build_win_amd64:
|
||||
name: 'Windows (x64) Installer'
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Windows Installer
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
type: [x86, x64, arm64]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build CPython installer
|
||||
run: .\Tools\msi\build.bat -x64
|
||||
run: .\Tools\msi\build.bat -${{ matrix.type }}
|
||||
|
|
|
|||
49
.github/workflows/doc.yml
vendored
49
.github/workflows/doc.yml
vendored
|
|
@ -5,6 +5,7 @@ on:
|
|||
#push:
|
||||
# branches:
|
||||
# - 'main'
|
||||
# - '3.11'
|
||||
# - '3.10'
|
||||
# - '3.9'
|
||||
# - '3.8'
|
||||
|
|
@ -14,6 +15,7 @@ on:
|
|||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
- '3.11'
|
||||
- '3.10'
|
||||
- '3.9'
|
||||
- '3.8'
|
||||
|
|
@ -21,15 +23,50 @@ on:
|
|||
paths:
|
||||
- 'Doc/**'
|
||||
- 'Misc/**'
|
||||
- '.github/workflows/doc.yml'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build_doc:
|
||||
name: 'Docs'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Register Sphinx problem matcher
|
||||
run: echo "::add-matcher::.github/problem-matchers/sphinx.json"
|
||||
- name: 'Set up Python'
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3'
|
||||
cache: 'pip'
|
||||
cache-dependency-path: 'Doc/requirements.txt'
|
||||
- name: 'Install build dependencies'
|
||||
run: make -C Doc/ venv
|
||||
- name: 'Check documentation'
|
||||
run: make -C Doc/ check
|
||||
- name: 'Build HTML documentation'
|
||||
run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html
|
||||
|
||||
# Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release
|
||||
doctest:
|
||||
name: 'Doctest'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Register Sphinx problem matcher
|
||||
run: echo "::add-matcher::.github/problem-matchers/sphinx.json"
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ubuntu-doc-${{ hashFiles('Doc/requirements.txt') }}
|
||||
restore-keys: |
|
||||
ubuntu-doc-
|
||||
- name: 'Install Dependencies'
|
||||
run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican
|
||||
- name: 'Configure CPython'
|
||||
|
|
@ -38,10 +75,6 @@ jobs:
|
|||
run: make -j4
|
||||
- name: 'Install build dependencies'
|
||||
run: make -C Doc/ PYTHON=../python venv
|
||||
- name: 'Build documentation'
|
||||
run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" doctest html
|
||||
- name: 'Upload'
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
with:
|
||||
name: doc-html
|
||||
path: Doc/build/html
|
||||
# Use "xvfb-run" since some doctest tests open GUI windows
|
||||
- name: 'Run documentation doctest'
|
||||
run: xvfb-run make -C Doc/ PYTHON=../python SPHINXERRORHANDLING="-W --keep-going" doctest
|
||||
|
|
|
|||
56
.github/workflows/new-bugs-announce-notifier.yml
vendored
Normal file
56
.github/workflows/new-bugs-announce-notifier.yml
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
name: new-bugs-announce notifier
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
|
||||
permissions:
|
||||
issues: read
|
||||
|
||||
jobs:
|
||||
notify-new-bugs-announce:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
- run: npm install mailgun.js form-data
|
||||
- name: Send notification
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
MAILGUN_API_KEY: ${{ secrets.PSF_MAILGUN_KEY }}
|
||||
with:
|
||||
script: |
|
||||
const Mailgun = require("mailgun.js");
|
||||
const formData = require('form-data');
|
||||
const mailgun = new Mailgun(formData);
|
||||
const DOMAIN = "mg.python.org";
|
||||
const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY});
|
||||
github.rest.issues.get({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
.then(function(issue) {
|
||||
const payload = {
|
||||
author : issue.data.user.login,
|
||||
issue : issue.data.number,
|
||||
title : issue.data.title,
|
||||
url : issue.data.html_url,
|
||||
labels : issue.data.labels.map(label => { return label.name }).join(", "),
|
||||
assignee : issue.data.assignees.map(assignee => { return assignee.login }),
|
||||
body : issue.data.body
|
||||
};
|
||||
|
||||
const data = {
|
||||
from: "CPython Issues <github@mg.python.org>",
|
||||
to: "new-bugs-announce@python.org",
|
||||
subject: `[Issue ${issue.data.number}] ${issue.data.title}`,
|
||||
template: "new-github-issue",
|
||||
'o:tracking-clicks': 'no',
|
||||
'h:X-Mailgun-Variables': JSON.stringify(payload)
|
||||
};
|
||||
return mg.messages.create(DOMAIN, data)
|
||||
})
|
||||
.then(msg => console.log(msg));
|
||||
1
.github/workflows/posix-deps-apt.sh
vendored
1
.github/workflows/posix-deps-apt.sh
vendored
|
|
@ -7,6 +7,7 @@ apt-get -yq install \
|
|||
ccache \
|
||||
gdb \
|
||||
lcov \
|
||||
libb2-dev \
|
||||
libbz2-dev \
|
||||
libffi-dev \
|
||||
libgdbm-dev \
|
||||
|
|
|
|||
31
.github/workflows/project-updater.yml
vendored
Normal file
31
.github/workflows/project-updater.yml
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
name: Update GH projects
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
add-to-project:
|
||||
name: Add issues to projects
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
# if an issue has any of these labels, it will be added
|
||||
# to the corresponding project
|
||||
- { project: 2, label: "release-blocker, deferred-blocker" }
|
||||
- { project: 3, label: expert-subinterpreters }
|
||||
- { project: 29, label: expert-asyncio }
|
||||
- { project: 32, label: sprint }
|
||||
|
||||
steps:
|
||||
- uses: actions/add-to-project@v0.1.0
|
||||
with:
|
||||
project-url: https://github.com/orgs/python/projects/${{ matrix.project }}
|
||||
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
|
||||
labeled: ${{ matrix.label }}
|
||||
8
.github/workflows/regen-abidump.sh
vendored
Normal file
8
.github/workflows/regen-abidump.sh
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
set -ex
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
./.github/workflows/posix-deps-apt.sh
|
||||
apt-get install -yq abigail-tools python3
|
||||
export CFLAGS="-g3 -O0"
|
||||
./configure --enable-shared && make
|
||||
make regen-abidump
|
||||
9
.github/workflows/stale.yml
vendored
9
.github/workflows/stale.yml
vendored
|
|
@ -9,14 +9,19 @@ permissions:
|
|||
|
||||
jobs:
|
||||
stale:
|
||||
if: github.repository_owner == 'python'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v4
|
||||
- name: "Check PRs"
|
||||
uses: actions/stale@v7
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity.'
|
||||
stale-pr-label: 'stale'
|
||||
days-before-stale: 30
|
||||
days-before-issue-stale: -1
|
||||
days-before-pr-stale: 30
|
||||
days-before-close: -1
|
||||
ascending: true
|
||||
operations-per-run: 120
|
||||
|
|
|
|||
32
.github/workflows/verify-ensurepip-wheels.yml
vendored
Normal file
32
.github/workflows/verify-ensurepip-wheels.yml
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
name: Verify bundled pip and setuptools
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'Lib/ensurepip/_bundled/**'
|
||||
- '.github/workflows/verify-ensurepip-wheels.yml'
|
||||
- 'Tools/build/verify_ensurepip_wheels.py'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'Lib/ensurepip/_bundled/**'
|
||||
- '.github/workflows/verify-ensurepip-wheels.yml'
|
||||
- 'Tools/build/verify_ensurepip_wheels.py'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3'
|
||||
- name: Compare checksums of bundled pip and setuptools to ones published on PyPI
|
||||
run: ./Tools/build/verify_ensurepip_wheels.py
|
||||
16
.gitignore
vendored
16
.gitignore
vendored
|
|
@ -5,11 +5,14 @@
|
|||
*.cover
|
||||
*.iml
|
||||
*.o
|
||||
*.lto
|
||||
*.a
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
*.dSYM
|
||||
*.dll
|
||||
*.wasm
|
||||
*.orig
|
||||
*.pyc
|
||||
*.pyd
|
||||
|
|
@ -38,7 +41,6 @@ gmon.out
|
|||
.DS_Store
|
||||
|
||||
*.exe
|
||||
!Lib/distutils/command/*.exe
|
||||
|
||||
# Ignore core dumps... but not Tools/msi/core/ or the like.
|
||||
core
|
||||
|
|
@ -55,8 +57,9 @@ Doc/.venv/
|
|||
Doc/env/
|
||||
Doc/.env/
|
||||
Include/pydtrace_probes.h
|
||||
Lib/distutils/command/*.pdb
|
||||
Lib/lib2to3/*.pickle
|
||||
Lib/site-packages/*
|
||||
!Lib/site-packages/README.txt
|
||||
Lib/test/data/*
|
||||
!Lib/test/data/README
|
||||
/_bootstrap_python
|
||||
|
|
@ -74,6 +77,7 @@ Mac/pythonw
|
|||
Misc/python.pc
|
||||
Misc/python-embed.pc
|
||||
Misc/python-config.sh
|
||||
Modules/Setup.bootstrap
|
||||
Modules/Setup.config
|
||||
Modules/Setup.local
|
||||
Modules/Setup.stdlib
|
||||
|
|
@ -110,10 +114,13 @@ PCbuild/win32/
|
|||
Tools/unicode/data/
|
||||
/autom4te.cache
|
||||
/build/
|
||||
/builddir/
|
||||
/config.cache
|
||||
/config.log
|
||||
/config.status
|
||||
/config.status.lineno
|
||||
# hendrikmuhs/ccache-action@v1
|
||||
/.ccache
|
||||
/platform
|
||||
/profile-clean-stamp
|
||||
/profile-run-stamp
|
||||
|
|
@ -135,7 +142,7 @@ Tools/ssl/win32
|
|||
Tools/freeze/test/outdir
|
||||
|
||||
# The frozen modules are always generated by the build so we don't
|
||||
# keep them in the repo. Also see Tools/scripts/freeze_modules.py.
|
||||
# keep them in the repo. Also see Tools/build/freeze_modules.py.
|
||||
Python/frozen_modules/*.h
|
||||
# The manifest can be generated at any time with "make regen-frozen".
|
||||
Python/frozen_modules/MANIFEST
|
||||
|
|
@ -144,3 +151,6 @@ Python/frozen_modules/MANIFEST
|
|||
# Ignore ./python binary on Unix but still look into ./Python/ directory.
|
||||
/python
|
||||
!/Python/
|
||||
|
||||
# main branch only: ABI files are not checked/maintained
|
||||
Doc/data/python*.abi
|
||||
|
|
|
|||
169
.travis.yml
169
.travis.yml
|
|
@ -1,169 +0,0 @@
|
|||
language: c
|
||||
dist: bionic
|
||||
|
||||
# To cache doc-building dependencies and C compiler output.
|
||||
cache:
|
||||
- pip
|
||||
- ccache
|
||||
- directories:
|
||||
- $HOME/multissl
|
||||
|
||||
env:
|
||||
global:
|
||||
- OPENSSL=1.1.1k
|
||||
- OPENSSL_DIR="$HOME/multissl/openssl/${OPENSSL}"
|
||||
- PATH="${OPENSSL_DIR}/bin:$PATH"
|
||||
- CFLAGS="-I${OPENSSL_DIR}/include"
|
||||
- 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"
|
||||
- PYTHONSTRICTEXTENSIONBUILD=1
|
||||
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
- /^\d\.\d+$/
|
||||
- buildbot-custom
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- env: OPTIONAL=true
|
||||
include:
|
||||
- name: "CPython tests"
|
||||
os: linux
|
||||
language: c
|
||||
compiler: clang
|
||||
# gcc also works, but to keep the # of concurrent builds down, we use one C
|
||||
# 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:
|
||||
- gdb
|
||||
- xvfb
|
||||
- name: "Documentation build"
|
||||
os: linux
|
||||
language: python
|
||||
# Build the docs against a stable version of Python so code bugs don't hold up doc-related PRs.
|
||||
python: 3.6
|
||||
env: TESTING=docs
|
||||
before_script:
|
||||
- cd Doc
|
||||
- make venv PYTHON=python
|
||||
script:
|
||||
- make check html SPHINXOPTS="-q -W -j4"
|
||||
- name: "Documentation tests"
|
||||
os: linux
|
||||
language: c
|
||||
compiler: clang
|
||||
env: TESTING=doctest
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- xvfb
|
||||
before_script:
|
||||
- ./configure
|
||||
- make -j4
|
||||
- make -C Doc/ PYTHON=../python venv
|
||||
script:
|
||||
xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W -j4" doctest
|
||||
|
||||
|
||||
before_install:
|
||||
- set -e
|
||||
- |
|
||||
# Check short-circuit conditions
|
||||
if [[ "${TESTING}" != "docs" && "${TESTING}" != "doctest" ]]
|
||||
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
|
||||
|
||||
install:
|
||||
- |
|
||||
# Install OpenSSL as necessary
|
||||
# Note: doctest needs OpenSSL
|
||||
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
|
||||
|
||||
# Travis provides only 2 cores, so don't overdo the parallelism and waste memory.
|
||||
before_script:
|
||||
# -Og is much faster than -O0
|
||||
- CFLAGS="${CFLAGS} -Og" ./configure --with-pydebug
|
||||
- eval "$(pyenv init -)"
|
||||
- pyenv global 3.8
|
||||
- PYTHON_FOR_REGEN=python3.8 make -j4 regen-all
|
||||
- make regen-stdlib-module-names
|
||||
- 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 -j4
|
||||
- make pythoninfo
|
||||
|
||||
script:
|
||||
# Using the built Python as patchcheck.py is built around the idea of using
|
||||
# a checkout-build of CPython to know things like what base branch the changes
|
||||
# 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
|
||||
# Check that all symbols exported by libpython start with "Py" or "_Py"
|
||||
- make smelly
|
||||
# Check that all symbols in the limited abi are present
|
||||
- make check-limited-abi
|
||||
# `-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
|
||||
irc:
|
||||
channels:
|
||||
# This is set to a secure variable to prevent forks from notifying the
|
||||
# IRC channel whenever they fail a build. This can be removed when travis
|
||||
# implements https://github.com/travis-ci/travis-ci/issues/1094.
|
||||
# The actual value here is: irc.freenode.net#python-dev
|
||||
- secure: "s7kAkpcom2yUJ8XqyjFI0obJmhAGrn1xmoivdaPdgBIA++X47TBp1x4pgDsbEsoalef7bEwa4l07KdT4qa+DOd/c4QxaWom7fbN3BuLVsZuVfODnl79+gYq/TAbGfyH+yDs18DXrUfPgwD7C5aW32ugsqAOd4iWzfGJQ5OrOZzqzGjYdYQUEkJFXgxDEIb4aHvxNDWGO3Po9uKISrhb5saQ0l776yLo1Ur7M4oxl8RTbCdgX0vf5TzPg52BgvZpOgt3DHOUYPeiJLKNjAE6ibg0U95sEvMfHX77nz4aFY4/3UI6FFaRla34rZ+mYKrn0TdxOhera1QOgPmM6HzdO4K44FpfK1DS0Xxk9U9/uApq+cG0bU3W+cVUHDBe5+90lpRBAXHeHCgT7TI8gec614aiT8lEr3+yH8OBRYGzkjNK8E2LJZ/SxnVxDe7aLF6AWcoWLfS6/ziAIBFQ5Nc4U72CT8fGVSkl8ywPiRlvixKdvTODMSZo0jMqlfZSNaAPTsNRx4wu5Uis4qekwe32Fz4aB6KGpsuuVjBi+H6v0RKxNJNGY3JKDiEH2TK0UE2auJ5GvLW48aUVFcQMB7euCWYXlSWVRHh3WLU8QXF29Dw4JduRZqUpOdRgMHU79UHRq+mkE0jAS/nBcS6CvsmxCpTSrfVYuMOu32yt18QQoTyU="
|
||||
on_success: change
|
||||
on_failure: always
|
||||
skip_join: true
|
||||
webhooks:
|
||||
urls:
|
||||
# For the same reasons as above for IRC, we encrypt the webhook address
|
||||
# for Zulip. The actual value is:
|
||||
# https://python.zulipchat.com/api/v1/external/travis?api_key=<api-key-redacted>&stream=core%2Ftest+runs
|
||||
- secure: "vLz2TodSL7wQ8DsIu86koRS9i4dsK40PH8+wzY93PBCCAzJAz113LTxK3/9PamMv+ObDRUSe5OpXcquE3d5Gwpu8IymF113qK0I3uNr+O3FtmKlj/Kd1P/V+z4pTpS3zh3lW9gyKV9EMWXIWS0IYKKZQU144XqUlIiucWK2jHJF/cSz2cRAx/6Kx68X4mZwEC7hiMOF4ZsWUMbCglM89ybeS0pr0kK9mmh88qsPyRQov3mRKswmVPlePk7clVLNAL43qSe3SzmrmACZfQ9KJYmpYnr/cjo2b6svYHcQBAwAUarZZ9KBMXeV7HwGWsSXAvHH2ynR0P++braBHGEMTGMSitdVWzFTmeiHnrkp08WAB+uFs54iEx3VklTk9bCzozTm2S94TRxbrsG9SypMvQxG570JV6P2XYuR+taCb/GMtMqrtGQm2e1Ht+nDLtiUb+/+rwEbicJJ13knptOQZI4tPOZESI/kXkORkSNwFfLSNLSl9jTlMmO7KjAAPApURHEdx26RbItAn8mIX2NcHTRjKn2qV4h3C54nmHmKWn/ZudHHJc6ieZSEUBoaLGAYmcWJRqrM6jiy2h9I9TRrCKAiGh5jT47FYKLwosTtV245l/ZhDb6eTVfEFT6TSLEoyfx9cCtTUvfMtXYl8eN9wlFYYpH8MSWbMD14eEkKBTWg="
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# Code of Conduct
|
||||
|
||||
Please note that all interactions on
|
||||
[Python Software Foundation](https://www.python.org/psf-landing/)-supported
|
||||
infrastructure is [covered](https://www.python.org/psf/records/board/minutes/2014-01-06/#management-of-the-psfs-web-properties)
|
||||
by the [PSF Code of Conduct](https://www.python.org/psf/codeofconduct/),
|
||||
which includes all the infrastructure used in the development of Python itself
|
||||
(e.g. mailing lists, issue trackers, GitHub, etc.).
|
||||
|
||||
In general, this means that everyone is expected to be **open**, **considerate**, and
|
||||
**respectful** of others no matter what their position is within the project.
|
||||
|
||||
51
Doc/Makefile
51
Doc/Makefile
|
|
@ -7,6 +7,7 @@
|
|||
PYTHON = python3
|
||||
VENVDIR = ./venv
|
||||
SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-build
|
||||
SPHINXLINT = PATH=$(VENVDIR)/bin:$$PATH sphinx-lint
|
||||
BLURB = PATH=$(VENVDIR)/bin:$$PATH blurb
|
||||
PAPER =
|
||||
SOURCES =
|
||||
|
|
@ -17,13 +18,10 @@ SPHINXERRORHANDLING = -W
|
|||
PAPEROPT_a4 = -D latex_elements.papersize=a4paper
|
||||
PAPEROPT_letter = -D latex_elements.papersize=letterpaper
|
||||
|
||||
ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) \
|
||||
ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) -j auto \
|
||||
$(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES)
|
||||
|
||||
.PHONY: help build html htmlhelp latex text texinfo changes linkcheck \
|
||||
suspicious coverage doctest pydoc-topics htmlview clean dist check serve \
|
||||
autobuild-dev autobuild-stable venv
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " clean to remove build files"
|
||||
|
|
@ -41,10 +39,9 @@ help:
|
|||
@echo " doctest to run doctests in the documentation"
|
||||
@echo " pydoc-topics to regenerate the pydoc topics file"
|
||||
@echo " dist to create a \"dist\" directory with archived docs for download"
|
||||
@echo " suspicious to check for suspicious markup in output text"
|
||||
@echo " check to run a check for frequent markup errors"
|
||||
@echo " serve to serve the documentation on the localhost (8000)"
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
-mkdir -p build
|
||||
# Look first for a Misc/NEWS file (building from a source release tarball
|
||||
|
|
@ -71,38 +68,46 @@ build:
|
|||
$(SPHINXBUILD) $(ALLSPHINXOPTS)
|
||||
@echo
|
||||
|
||||
.PHONY: html
|
||||
html: BUILDER = html
|
||||
html: build
|
||||
@echo "Build finished. The HTML pages are in build/html."
|
||||
|
||||
.PHONY: htmlhelp
|
||||
htmlhelp: BUILDER = htmlhelp
|
||||
htmlhelp: build
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
"build/htmlhelp/pydoc.hhp project file."
|
||||
|
||||
.PHONY: latex
|
||||
latex: BUILDER = latex
|
||||
latex: build
|
||||
@echo "Build finished; the LaTeX files are in build/latex."
|
||||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||
"run these through (pdf)latex."
|
||||
|
||||
.PHONY: text
|
||||
text: BUILDER = text
|
||||
text: build
|
||||
@echo "Build finished; the text files are in build/text."
|
||||
|
||||
.PHONY: texinfo
|
||||
texinfo: BUILDER = texinfo
|
||||
texinfo: build
|
||||
@echo "Build finished; the python.texi file is in build/texinfo."
|
||||
@echo "Run \`make info' in that directory to run it through makeinfo."
|
||||
|
||||
.PHONY: epub
|
||||
epub: BUILDER = epub
|
||||
epub: build
|
||||
@echo "Build finished; the epub files are in build/epub."
|
||||
|
||||
.PHONY: changes
|
||||
changes: BUILDER = changes
|
||||
changes: build
|
||||
@echo "The overview file is in build/changes."
|
||||
|
||||
.PHONY: linkcheck
|
||||
linkcheck: BUILDER = linkcheck
|
||||
linkcheck:
|
||||
@$(MAKE) build BUILDER=$(BUILDER) || { \
|
||||
|
|
@ -110,18 +115,12 @@ linkcheck:
|
|||
"or in build/$(BUILDER)/output.txt"; \
|
||||
false; }
|
||||
|
||||
suspicious: BUILDER = suspicious
|
||||
suspicious:
|
||||
@$(MAKE) build BUILDER=$(BUILDER) || { \
|
||||
echo "Suspicious check complete; look for any errors in the above output" \
|
||||
"or in build/$(BUILDER)/suspicious.csv. If all issues are false" \
|
||||
"positives, append that file to tools/susp-ignored.csv."; \
|
||||
false; }
|
||||
|
||||
.PHONY: coverage
|
||||
coverage: BUILDER = coverage
|
||||
coverage: build
|
||||
@echo "Coverage finished; see c.txt and python.txt in build/coverage"
|
||||
|
||||
.PHONY: doctest
|
||||
doctest: BUILDER = doctest
|
||||
doctest:
|
||||
@$(MAKE) build BUILDER=$(BUILDER) || { \
|
||||
|
|
@ -129,20 +128,25 @@ doctest:
|
|||
"results in build/doctest/output.txt"; \
|
||||
false; }
|
||||
|
||||
.PHONY: pydoc-topics
|
||||
pydoc-topics: BUILDER = pydoc-topics
|
||||
pydoc-topics: build
|
||||
@echo "Building finished; now run this:" \
|
||||
"cp build/pydoc-topics/topics.py ../Lib/pydoc_data/topics.py"
|
||||
|
||||
.PHONY: htmlview
|
||||
htmlview: html
|
||||
$(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
|
||||
$(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/html/index.html'))"
|
||||
|
||||
.PHONY: clean
|
||||
clean: clean-venv
|
||||
-rm -rf build/*
|
||||
|
||||
.PHONY: clean-venv
|
||||
clean-venv:
|
||||
rm -rf $(VENVDIR)
|
||||
|
||||
.PHONY: venv
|
||||
venv:
|
||||
@if [ -d $(VENVDIR) ] ; then \
|
||||
echo "venv already exists."; \
|
||||
|
|
@ -154,6 +158,7 @@ venv:
|
|||
echo "The venv has been created in the $(VENVDIR) directory"; \
|
||||
fi
|
||||
|
||||
.PHONY: dist
|
||||
dist:
|
||||
rm -rf dist
|
||||
mkdir -p dist
|
||||
|
|
@ -208,12 +213,16 @@ dist:
|
|||
rm -r dist/python-$(DISTVERSION)-docs-texinfo
|
||||
rm dist/python-$(DISTVERSION)-docs-texinfo.tar
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
$(PYTHON) tools/rstlint.py -i tools -i $(VENVDIR) -i README.rst
|
||||
$(PYTHON) tools/rstlint.py ../Misc/NEWS.d/next/
|
||||
# Check the docs and NEWS files with sphinx-lint.
|
||||
# Ignore the tools and venv dirs and check that the default role is not used.
|
||||
$(SPHINXLINT) -i tools -i $(VENVDIR) --enable default-role
|
||||
$(SPHINXLINT) --enable default-role ../Misc/NEWS.d/next/
|
||||
|
||||
.PHONY: serve
|
||||
serve:
|
||||
$(PYTHON) ../Tools/scripts/serve.py build/html
|
||||
@echo "The serve target was removed, use htmlview instead (see bpo-36329)"
|
||||
|
||||
# Targets for daily automated doc build
|
||||
# By default, Sphinx only rebuilds pages where the page content has changed.
|
||||
|
|
@ -223,15 +232,18 @@ serve:
|
|||
# output files)
|
||||
|
||||
# for development releases: always build
|
||||
.PHONY: autobuild-dev
|
||||
autobuild-dev:
|
||||
make dist SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1'
|
||||
|
||||
# for quick rebuilds (HTML only)
|
||||
.PHONY: autobuild-dev-html
|
||||
autobuild-dev-html:
|
||||
make html SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1'
|
||||
|
||||
# for stable releases: only build if not in pre-release stage (alpha, beta)
|
||||
# release candidate downloads are okay, since the stable tree can be in that stage
|
||||
.PHONY: autobuild-stable
|
||||
autobuild-stable:
|
||||
@case $(DISTVERSION) in *[ab]*) \
|
||||
echo "Not building; $(DISTVERSION) is not a release version."; \
|
||||
|
|
@ -239,6 +251,7 @@ autobuild-stable:
|
|||
esac
|
||||
@make autobuild-dev
|
||||
|
||||
.PHONY: autobuild-stable-html
|
||||
autobuild-stable-html:
|
||||
@case $(DISTVERSION) in *[ab]*) \
|
||||
echo "Not building; $(DISTVERSION) is not a release version."; \
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ If you'd like to create the virtual environment in a different location,
|
|||
you can specify it using the ``VENVDIR`` variable.
|
||||
|
||||
You can also skip creating the virtual environment altogether, in which case
|
||||
the Makefile will look for instances of ``sphinxbuild`` and ``blurb``
|
||||
the Makefile will look for instances of ``sphinx-build`` and ``blurb``
|
||||
installed on your process ``PATH`` (configurable with the ``SPHINXBUILD`` and
|
||||
``BLURB`` variables).
|
||||
|
||||
|
|
@ -91,10 +91,7 @@ Available make targets are:
|
|||
|
||||
* "pydoc-topics", which builds a Python module containing a dictionary with
|
||||
plain text documentation for the labels defined in
|
||||
`tools/pyspecific.py` -- pydoc needs these to show topic and keyword help.
|
||||
|
||||
* "suspicious", which checks the parsed markup for text that looks like
|
||||
malformed and thus unconverted reST.
|
||||
``tools/pyspecific.py`` -- pydoc needs these to show topic and keyword help.
|
||||
|
||||
* "check", which checks for frequent markup errors.
|
||||
|
||||
|
|
@ -130,7 +127,7 @@ Contributing
|
|||
============
|
||||
|
||||
Bugs in the content should be reported to the
|
||||
`Python bug tracker <https://bugs.python.org>`_.
|
||||
`Python bug tracker <https://github.com/python/cpython/issues>`_.
|
||||
|
||||
Bugs in the toolset should be reported to the tools themselves.
|
||||
|
||||
|
|
|
|||
BIN
Doc/_static/og-image.png
Normal file
BIN
Doc/_static/og-image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -6,8 +6,8 @@ About these documents
|
|||
These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a
|
||||
document processor specifically written for the Python documentation.
|
||||
|
||||
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
|
||||
.. _Sphinx: http://sphinx-doc.org/
|
||||
.. _reStructuredText: https://docutils.sourceforge.io/rst.html
|
||||
.. _Sphinx: https://www.sphinx-doc.org/
|
||||
|
||||
.. In the online version of these documents, you can submit comments and suggest
|
||||
changes directly on the documentation pages.
|
||||
|
|
@ -21,7 +21,7 @@ Many thanks go to:
|
|||
|
||||
* Fred L. Drake, Jr., the creator of the original Python documentation toolset
|
||||
and writer of much of the content;
|
||||
* the `Docutils <http://docutils.sourceforge.net/>`_ project for creating
|
||||
* the `Docutils <https://docutils.sourceforge.io/>`_ project for creating
|
||||
reStructuredText and the Docutils suite;
|
||||
* Fredrik Lundh for his Alternative Python Reference project from which Sphinx
|
||||
got many good ideas.
|
||||
|
|
|
|||
43
Doc/bugs.rst
43
Doc/bugs.rst
|
|
@ -35,43 +35,48 @@ though it may take a while to be processed.
|
|||
`Helping with Documentation <https://devguide.python.org/docquality/#helping-with-documentation>`_
|
||||
Comprehensive guide for individuals that are interested in contributing to Python documentation.
|
||||
|
||||
`Documentation Translations <https://devguide.python.org/documenting/#translating>`_
|
||||
A list of GitHub pages for documentation translation and their primary contacts.
|
||||
|
||||
|
||||
.. _using-the-tracker:
|
||||
|
||||
Using the Python issue tracker
|
||||
==============================
|
||||
|
||||
Bug reports for Python itself should be submitted via the Python Bug Tracker
|
||||
(https://bugs.python.org/). The bug tracker offers a web form which allows
|
||||
pertinent information to be entered and submitted to the developers.
|
||||
Issue reports for Python itself should be submitted via the GitHub issues
|
||||
tracker (https://github.com/python/cpython/issues).
|
||||
The GitHub issues tracker offers a web form which allows pertinent information
|
||||
to be entered and submitted to the developers.
|
||||
|
||||
The first step in filing a report is to determine whether the problem has
|
||||
already been reported. The advantage in doing so, aside from saving the
|
||||
developers time, is that you learn what has been done to fix it; it may be that
|
||||
developers' time, is that you learn what has been done to fix it; it may be that
|
||||
the problem has already been fixed for the next release, or additional
|
||||
information is needed (in which case you are welcome to provide it if you can!).
|
||||
To do this, search the bug database using the search box on the top of the page.
|
||||
To do this, search the tracker using the search box at the top of the page.
|
||||
|
||||
If the problem you're reporting is not already in the bug tracker, go back to
|
||||
the Python Bug Tracker and log in. If you don't already have a tracker account,
|
||||
select the "Register" link or, if you use OpenID, one of the OpenID provider
|
||||
logos in the sidebar. It is not possible to submit a bug report anonymously.
|
||||
If the problem you're reporting is not already in the list, log in to GitHub.
|
||||
If you don't already have a GitHub account, create a new account using the
|
||||
"Sign up" link.
|
||||
It is not possible to submit a bug report anonymously.
|
||||
|
||||
Being now logged in, you can submit a bug. Select the "Create New" link in the
|
||||
sidebar to open the bug reporting form.
|
||||
Being now logged in, you can submit an issue.
|
||||
Click on the "New issue" button in the top bar to report a new issue.
|
||||
|
||||
The submission form has a number of fields. For the "Title" field, enter a
|
||||
*very* short description of the problem; less than ten words is good. In the
|
||||
"Type" field, select the type of your problem; also select the "Component" and
|
||||
"Versions" to which the bug relates.
|
||||
The submission form has two fields, "Title" and "Comment".
|
||||
|
||||
For the "Title" field, enter a *very* short description of the problem;
|
||||
less than ten words is good.
|
||||
|
||||
In the "Comment" field, describe the problem in detail, including what you
|
||||
expected to happen and what did happen. Be sure to include whether any
|
||||
extension modules were involved, and what hardware and software platform you
|
||||
were using (including version information as appropriate).
|
||||
|
||||
Each bug report will be assigned to a developer who will determine what needs to
|
||||
be done to correct the problem. You will receive an update each time action is
|
||||
taken on the bug.
|
||||
Each issue report will be reviewed by a developer who will determine what needs to
|
||||
be done to correct the problem. You will receive an update each time an action is
|
||||
taken on the issue.
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
|
@ -95,6 +100,6 @@ patching Python in the `Python Developer's Guide`_. If you have questions,
|
|||
the `core-mentorship mailing list`_ is a friendly place to get answers to
|
||||
any and all questions pertaining to the process of fixing issues in Python.
|
||||
|
||||
.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity
|
||||
.. _Documentation bugs: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Adocs
|
||||
.. _Python Developer's Guide: https://devguide.python.org/
|
||||
.. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Allocating Objects on the Heap
|
|||
|
||||
.. c:function:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type)
|
||||
|
||||
Initialize a newly-allocated object *op* with its type and initial
|
||||
Initialize a newly allocated object *op* with its type and initial
|
||||
reference. Returns the initialized object. If *type* indicates that the
|
||||
object participates in the cyclic garbage detector, it is added to the
|
||||
detector's set of observed objects. Other fields of the object are not
|
||||
|
|
|
|||
|
|
@ -58,5 +58,16 @@ See :ref:`stable` for a discussion of API and ABI stability across versions.
|
|||
Thus ``3.4.1a2`` is hexversion ``0x030401a2`` and ``3.10.0`` is
|
||||
hexversion ``0x030a00f0``.
|
||||
|
||||
Use this for numeric comparisons, e.g. ``#if PY_VERSION_HEX >= ...``.
|
||||
|
||||
This version is also available via the symbol :data:`Py_Version`.
|
||||
|
||||
.. c:var:: const unsigned long Py_Version
|
||||
|
||||
The Python runtime version number encoded in a single constant integer, with
|
||||
the same format as the :c:macro:`PY_VERSION_HEX` macro.
|
||||
This contains the Python version used at run time.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
All the given macros are defined in :source:`Include/patchlevel.h`.
|
||||
|
|
|
|||
|
|
@ -34,24 +34,39 @@ These formats allow accessing an object as a contiguous chunk of memory.
|
|||
You don't have to provide raw storage for the returned unicode or bytes
|
||||
area.
|
||||
|
||||
In general, when a format sets a pointer to a buffer, the buffer is
|
||||
managed by the corresponding Python object, and the buffer shares
|
||||
the lifetime of this object. You won't have to release any memory yourself.
|
||||
The only exceptions are ``es``, ``es#``, ``et`` and ``et#``.
|
||||
|
||||
However, when a :c:type:`Py_buffer` structure gets filled, the underlying
|
||||
buffer is locked so that the caller can subsequently use the buffer even
|
||||
inside a :c:type:`Py_BEGIN_ALLOW_THREADS` block without the risk of mutable data
|
||||
being resized or destroyed. As a result, **you have to call**
|
||||
:c:func:`PyBuffer_Release` after you have finished processing the data (or
|
||||
in any early abort case).
|
||||
|
||||
Unless otherwise stated, buffers are not NUL-terminated.
|
||||
|
||||
Some formats require a read-only :term:`bytes-like object`, and set a
|
||||
pointer instead of a buffer structure. They work by checking that
|
||||
the object's :c:member:`PyBufferProcs.bf_releasebuffer` field is ``NULL``,
|
||||
which disallows mutable objects such as :class:`bytearray`.
|
||||
There are three ways strings and buffers can be converted to C:
|
||||
|
||||
* Formats such as ``y*`` and ``s*`` fill a :c:type:`Py_buffer` structure.
|
||||
This locks the underlying buffer so that the caller can subsequently use
|
||||
the buffer even inside a :c:type:`Py_BEGIN_ALLOW_THREADS`
|
||||
block without the risk of mutable data being resized or destroyed.
|
||||
As a result, **you have to call** :c:func:`PyBuffer_Release` after you have
|
||||
finished processing the data (or in any early abort case).
|
||||
|
||||
* The ``es``, ``es#``, ``et`` and ``et#`` formats allocate the result buffer.
|
||||
**You have to call** :c:func:`PyMem_Free` after you have finished
|
||||
processing the data (or in any early abort case).
|
||||
|
||||
* .. _c-arg-borrowed-buffer:
|
||||
|
||||
Other formats take a :class:`str` or a read-only :term:`bytes-like object`,
|
||||
such as :class:`bytes`, and provide a ``const char *`` pointer to
|
||||
its buffer.
|
||||
In this case the buffer is "borrowed": it is managed by the corresponding
|
||||
Python object, and shares the lifetime of this object.
|
||||
You won't have to release any memory yourself.
|
||||
|
||||
To ensure that the underlying buffer may be safely borrowed, the object's
|
||||
:c:member:`PyBufferProcs.bf_releasebuffer` field must be ``NULL``.
|
||||
This disallows common mutable objects such as :class:`bytearray`,
|
||||
but also some read-only objects such as :class:`memoryview` of
|
||||
:class:`bytes`.
|
||||
|
||||
Besides this ``bf_releasebuffer`` requirement, there is no check to verify
|
||||
whether the input object is immutable (e.g. whether it would honor a request
|
||||
for a writable buffer, or whether another thread can mutate the data).
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -89,7 +104,7 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
Unicode objects are converted to C strings using ``'utf-8'`` encoding.
|
||||
|
||||
``s#`` (:class:`str`, read-only :term:`bytes-like object`) [const char \*, :c:type:`Py_ssize_t`]
|
||||
Like ``s*``, except that it doesn't accept mutable objects.
|
||||
Like ``s*``, except that it provides a :ref:`borrowed buffer <c-arg-borrowed-buffer>`.
|
||||
The result is stored into two C variables,
|
||||
the first one a pointer to a C string, the second one its length.
|
||||
The string may contain embedded null bytes. Unicode objects are converted
|
||||
|
|
@ -108,8 +123,9 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
pointer is set to ``NULL``.
|
||||
|
||||
``y`` (read-only :term:`bytes-like object`) [const char \*]
|
||||
This format converts a bytes-like object to a C pointer to a character
|
||||
string; it does not accept Unicode objects. The bytes buffer must not
|
||||
This format converts a bytes-like object to a C pointer to a
|
||||
:ref:`borrowed <c-arg-borrowed-buffer>` character string;
|
||||
it does not accept Unicode objects. The bytes buffer must not
|
||||
contain embedded null bytes; if it does, a :exc:`ValueError`
|
||||
exception is raised.
|
||||
|
||||
|
|
@ -129,59 +145,17 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
``S`` (:class:`bytes`) [PyBytesObject \*]
|
||||
Requires that the Python object is a :class:`bytes` object, without
|
||||
attempting any conversion. Raises :exc:`TypeError` if the object is not
|
||||
a bytes object. The C variable may also be declared as :c:type:`PyObject*`.
|
||||
a bytes object. The C variable may also be declared as :c:expr:`PyObject*`.
|
||||
|
||||
``Y`` (:class:`bytearray`) [PyByteArrayObject \*]
|
||||
Requires that the Python object is a :class:`bytearray` object, without
|
||||
attempting any conversion. Raises :exc:`TypeError` if the object is not
|
||||
a :class:`bytearray` object. The C variable may also be declared as :c:type:`PyObject*`.
|
||||
|
||||
``u`` (:class:`str`) [const Py_UNICODE \*]
|
||||
Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of
|
||||
Unicode characters. You must pass the address of a :c:type:`Py_UNICODE`
|
||||
pointer variable, which will be filled with the pointer to an existing
|
||||
Unicode buffer. Please note that the width of a :c:type:`Py_UNICODE`
|
||||
character depends on compilation options (it is either 16 or 32 bits).
|
||||
The Python string must not contain embedded null code points; if it does,
|
||||
a :exc:`ValueError` exception is raised.
|
||||
|
||||
.. versionchanged:: 3.5
|
||||
Previously, :exc:`TypeError` was raised when embedded null code points
|
||||
were encountered in the Python string.
|
||||
|
||||
.. deprecated-removed:: 3.3 3.12
|
||||
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
|
||||
:c:func:`PyUnicode_AsWideCharString`.
|
||||
|
||||
``u#`` (:class:`str`) [const Py_UNICODE \*, :c:type:`Py_ssize_t`]
|
||||
This variant on ``u`` stores into two C variables, the first one a pointer to a
|
||||
Unicode data buffer, the second one its length. This variant allows
|
||||
null code points.
|
||||
|
||||
.. deprecated-removed:: 3.3 3.12
|
||||
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 3.12
|
||||
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 \*, :c:type:`Py_ssize_t`]
|
||||
Like ``u#``, but the Python object may also be ``None``, in which case the
|
||||
:c:type:`Py_UNICODE` pointer is set to ``NULL``.
|
||||
|
||||
.. deprecated-removed:: 3.3 3.12
|
||||
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
|
||||
:c:func:`PyUnicode_AsWideCharString`.
|
||||
a :class:`bytearray` object. The C variable may also be declared as :c:expr:`PyObject*`.
|
||||
|
||||
``U`` (:class:`str`) [PyObject \*]
|
||||
Requires that the Python object is a Unicode object, without attempting
|
||||
any conversion. Raises :exc:`TypeError` if the object is not a Unicode
|
||||
object. The C variable may also be declared as :c:type:`PyObject*`.
|
||||
object. The C variable may also be declared as :c:expr:`PyObject*`.
|
||||
|
||||
``w*`` (read-write :term:`bytes-like object`) [Py_buffer]
|
||||
This format accepts any object which implements the read-write buffer
|
||||
|
|
@ -194,10 +168,10 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
It only works for encoded data without embedded NUL bytes.
|
||||
|
||||
This format requires two arguments. The first is only used as input, and
|
||||
must be a :c:type:`const char*` which points to the name of an encoding as a
|
||||
must be a :c:expr:`const char*` which points to the name of an encoding as a
|
||||
NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
|
||||
An exception is raised if the named encoding is not known to Python. The
|
||||
second argument must be a :c:type:`char**`; the value of the pointer it
|
||||
second argument must be a :c:expr:`char**`; the value of the pointer it
|
||||
references will be set to a buffer with the contents of the argument text.
|
||||
The text will be encoded in the encoding specified by the first argument.
|
||||
|
||||
|
|
@ -217,10 +191,10 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
characters.
|
||||
|
||||
It requires three arguments. The first is only used as input, and must be a
|
||||
:c:type:`const char*` which points to the name of an encoding as a
|
||||
:c:expr:`const char*` which points to the name of an encoding as a
|
||||
NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used.
|
||||
An exception is raised if the named encoding is not known to Python. The
|
||||
second argument must be a :c:type:`char**`; the value of the pointer it
|
||||
second argument must be a :c:expr:`char**`; the value of the pointer it
|
||||
references will be set to a buffer with the contents of the argument text.
|
||||
The text will be encoded in the encoding specified by the first argument.
|
||||
The third argument must be a pointer to an integer; the referenced integer
|
||||
|
|
@ -247,64 +221,69 @@ which disallows mutable objects such as :class:`bytearray`.
|
|||
them. Instead, the implementation assumes that the byte string object uses the
|
||||
encoding passed in as parameter.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
``u``, ``u#``, ``Z``, and ``Z#`` are removed because they used a legacy
|
||||
``Py_UNICODE*`` representation.
|
||||
|
||||
|
||||
Numbers
|
||||
-------
|
||||
|
||||
``b`` (:class:`int`) [unsigned char]
|
||||
Convert a nonnegative Python integer to an unsigned tiny int, stored in a C
|
||||
:c:type:`unsigned char`.
|
||||
:c:expr:`unsigned char`.
|
||||
|
||||
``B`` (:class:`int`) [unsigned char]
|
||||
Convert a Python integer to a tiny int without overflow checking, stored in a C
|
||||
:c:type:`unsigned char`.
|
||||
:c:expr:`unsigned char`.
|
||||
|
||||
``h`` (:class:`int`) [short int]
|
||||
Convert a Python integer to a C :c:type:`short int`.
|
||||
Convert a Python integer to a C :c:expr:`short int`.
|
||||
|
||||
``H`` (:class:`int`) [unsigned short int]
|
||||
Convert a Python integer to a C :c:type:`unsigned short int`, without overflow
|
||||
Convert a Python integer to a C :c:expr:`unsigned short int`, without overflow
|
||||
checking.
|
||||
|
||||
``i`` (:class:`int`) [int]
|
||||
Convert a Python integer to a plain C :c:type:`int`.
|
||||
Convert a Python integer to a plain C :c:expr:`int`.
|
||||
|
||||
``I`` (:class:`int`) [unsigned int]
|
||||
Convert a Python integer to a C :c:type:`unsigned int`, without overflow
|
||||
Convert a Python integer to a C :c:expr:`unsigned int`, without overflow
|
||||
checking.
|
||||
|
||||
``l`` (:class:`int`) [long int]
|
||||
Convert a Python integer to a C :c:type:`long int`.
|
||||
Convert a Python integer to a C :c:expr:`long int`.
|
||||
|
||||
``k`` (:class:`int`) [unsigned long]
|
||||
Convert a Python integer to a C :c:type:`unsigned long` without
|
||||
Convert a Python integer to a C :c:expr:`unsigned long` without
|
||||
overflow checking.
|
||||
|
||||
``L`` (:class:`int`) [long long]
|
||||
Convert a Python integer to a C :c:type:`long long`.
|
||||
Convert a Python integer to a C :c:expr:`long long`.
|
||||
|
||||
``K`` (:class:`int`) [unsigned long long]
|
||||
Convert a Python integer to a C :c:type:`unsigned long long`
|
||||
Convert a Python integer to a C :c:expr:`unsigned long long`
|
||||
without overflow checking.
|
||||
|
||||
``n`` (:class:`int`) [Py_ssize_t]
|
||||
``n`` (:class:`int`) [:c:type:`Py_ssize_t`]
|
||||
Convert a Python integer to a C :c:type:`Py_ssize_t`.
|
||||
|
||||
``c`` (:class:`bytes` or :class:`bytearray` of length 1) [char]
|
||||
Convert a Python byte, represented as a :class:`bytes` or
|
||||
:class:`bytearray` object of length 1, to a C :c:type:`char`.
|
||||
:class:`bytearray` object of length 1, to a C :c:expr:`char`.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Allow :class:`bytearray` objects.
|
||||
|
||||
``C`` (:class:`str` of length 1) [int]
|
||||
Convert a Python character, represented as a :class:`str` object of
|
||||
length 1, to a C :c:type:`int`.
|
||||
length 1, to a C :c:expr:`int`.
|
||||
|
||||
``f`` (:class:`float`) [float]
|
||||
Convert a Python floating point number to a C :c:type:`float`.
|
||||
Convert a Python floating point number to a C :c:expr:`float`.
|
||||
|
||||
``d`` (:class:`float`) [double]
|
||||
Convert a Python floating point number to a C :c:type:`double`.
|
||||
Convert a Python floating point number to a C :c:expr:`double`.
|
||||
|
||||
``D`` (:class:`complex`) [Py_complex]
|
||||
Convert a Python complex number to a C :c:type:`Py_complex` structure.
|
||||
|
|
@ -320,7 +299,7 @@ Other objects
|
|||
``O!`` (object) [*typeobject*, PyObject \*]
|
||||
Store a Python object in a C object pointer. This is similar to ``O``, but
|
||||
takes two C arguments: the first is the address of a Python type object, the
|
||||
second is the address of the C variable (of type :c:type:`PyObject*`) into which
|
||||
second is the address of the C variable (of type :c:expr:`PyObject*`) into which
|
||||
the object pointer is stored. If the Python object does not have the required
|
||||
type, :exc:`TypeError` is raised.
|
||||
|
||||
|
|
@ -329,13 +308,13 @@ Other objects
|
|||
``O&`` (object) [*converter*, *anything*]
|
||||
Convert a Python object to a C variable through a *converter* function. This
|
||||
takes two arguments: the first is a function, the second is the address of a C
|
||||
variable (of arbitrary type), converted to :c:type:`void *`. The *converter*
|
||||
variable (of arbitrary type), converted to :c:expr:`void *`. The *converter*
|
||||
function in turn is called as follows::
|
||||
|
||||
status = converter(object, address);
|
||||
|
||||
where *object* is the Python object to be converted and *address* is the
|
||||
:c:type:`void*` argument that was passed to the :c:func:`PyArg_Parse\*` function.
|
||||
:c:expr:`void*` argument that was passed to the ``PyArg_Parse*`` function.
|
||||
The returned *status* should be ``1`` for a successful conversion and ``0`` if
|
||||
the conversion has failed. When the conversion fails, the *converter* function
|
||||
should raise an exception and leave the content of *address* unmodified.
|
||||
|
|
@ -409,9 +388,9 @@ what is specified for the corresponding format unit in that case.
|
|||
|
||||
For the conversion to succeed, the *arg* object must match the format
|
||||
and the format must be exhausted. On success, the
|
||||
:c:func:`PyArg_Parse\*` functions return true, otherwise they return
|
||||
``PyArg_Parse*`` functions return true, otherwise they return
|
||||
false and raise an appropriate exception. When the
|
||||
:c:func:`PyArg_Parse\*` functions fail due to conversion failure in one
|
||||
``PyArg_Parse*`` functions fail due to conversion failure in one
|
||||
of the format units, the variables at the addresses corresponding to that
|
||||
and the following format units are left untouched.
|
||||
|
||||
|
|
@ -481,7 +460,7 @@ API Functions
|
|||
*args*; it must actually be a tuple. The length of the tuple must be at least
|
||||
*min* and no more than *max*; *min* and *max* may be equal. Additional
|
||||
arguments must be passed to the function, each of which should be a pointer to a
|
||||
:c:type:`PyObject*` variable; these will be filled in with the values from
|
||||
:c:expr:`PyObject*` variable; these will be filled in with the values from
|
||||
*args*; they will contain :term:`borrowed references <borrowed reference>`.
|
||||
The variables which correspond
|
||||
to optional parameters not given by *args* will not be filled in; these should
|
||||
|
|
@ -518,7 +497,7 @@ Building values
|
|||
.. c:function:: PyObject* Py_BuildValue(const char *format, ...)
|
||||
|
||||
Create a new value based on a format string similar to those accepted by the
|
||||
:c:func:`PyArg_Parse\*` family of functions and a sequence of values. Returns
|
||||
``PyArg_Parse*`` family of functions and a sequence of values. Returns
|
||||
the value or ``NULL`` in the case of an error; an exception will be raised if
|
||||
``NULL`` is returned.
|
||||
|
||||
|
|
@ -568,7 +547,7 @@ Building values
|
|||
Same as ``s#``.
|
||||
|
||||
``u`` (:class:`str`) [const wchar_t \*]
|
||||
Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4)
|
||||
Convert a null-terminated :c:expr:`wchar_t` buffer of Unicode (UTF-16 or UCS-4)
|
||||
data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``,
|
||||
``None`` is returned.
|
||||
|
||||
|
|
@ -584,51 +563,51 @@ Building values
|
|||
Same as ``s#``.
|
||||
|
||||
``i`` (:class:`int`) [int]
|
||||
Convert a plain C :c:type:`int` to a Python integer object.
|
||||
Convert a plain C :c:expr:`int` to a Python integer object.
|
||||
|
||||
``b`` (:class:`int`) [char]
|
||||
Convert a plain C :c:type:`char` to a Python integer object.
|
||||
Convert a plain C :c:expr:`char` to a Python integer object.
|
||||
|
||||
``h`` (:class:`int`) [short int]
|
||||
Convert a plain C :c:type:`short int` to a Python integer object.
|
||||
Convert a plain C :c:expr:`short int` to a Python integer object.
|
||||
|
||||
``l`` (:class:`int`) [long int]
|
||||
Convert a C :c:type:`long int` to a Python integer object.
|
||||
Convert a C :c:expr:`long int` to a Python integer object.
|
||||
|
||||
``B`` (:class:`int`) [unsigned char]
|
||||
Convert a C :c:type:`unsigned char` to a Python integer object.
|
||||
Convert a C :c:expr:`unsigned char` to a Python integer object.
|
||||
|
||||
``H`` (:class:`int`) [unsigned short int]
|
||||
Convert a C :c:type:`unsigned short int` to a Python integer object.
|
||||
Convert a C :c:expr:`unsigned short int` to a Python integer object.
|
||||
|
||||
``I`` (:class:`int`) [unsigned int]
|
||||
Convert a C :c:type:`unsigned int` to a Python integer object.
|
||||
Convert a C :c:expr:`unsigned int` to a Python integer object.
|
||||
|
||||
``k`` (:class:`int`) [unsigned long]
|
||||
Convert a C :c:type:`unsigned long` to a Python integer object.
|
||||
Convert a C :c:expr:`unsigned long` to a Python integer object.
|
||||
|
||||
``L`` (:class:`int`) [long long]
|
||||
Convert a C :c:type:`long long` to a Python integer object.
|
||||
Convert a C :c:expr:`long long` to a Python integer object.
|
||||
|
||||
``K`` (:class:`int`) [unsigned long long]
|
||||
Convert a C :c:type:`unsigned long long` to a Python integer object.
|
||||
Convert a C :c:expr:`unsigned long long` to a Python integer object.
|
||||
|
||||
``n`` (:class:`int`) [Py_ssize_t]
|
||||
``n`` (:class:`int`) [:c:type:`Py_ssize_t`]
|
||||
Convert a C :c:type:`Py_ssize_t` to a Python integer.
|
||||
|
||||
``c`` (:class:`bytes` of length 1) [char]
|
||||
Convert a C :c:type:`int` representing a byte to a Python :class:`bytes` object of
|
||||
Convert a C :c:expr:`int` representing a byte to a Python :class:`bytes` object of
|
||||
length 1.
|
||||
|
||||
``C`` (:class:`str` of length 1) [int]
|
||||
Convert a C :c:type:`int` representing a character to Python :class:`str`
|
||||
Convert a C :c:expr:`int` representing a character to Python :class:`str`
|
||||
object of length 1.
|
||||
|
||||
``d`` (:class:`float`) [double]
|
||||
Convert a C :c:type:`double` to a Python floating point number.
|
||||
Convert a C :c:expr:`double` to a Python floating point number.
|
||||
|
||||
``f`` (:class:`float`) [float]
|
||||
Convert a C :c:type:`float` to a Python floating point number.
|
||||
Convert a C :c:expr:`float` to a Python floating point number.
|
||||
|
||||
``D`` (:class:`complex`) [Py_complex \*]
|
||||
Convert a C :c:type:`Py_complex` structure to a Python complex number.
|
||||
|
|
@ -651,7 +630,7 @@ Building values
|
|||
|
||||
``O&`` (object) [*converter*, *anything*]
|
||||
Convert *anything* to a Python object through a *converter* function. The
|
||||
function is called with *anything* (which should be compatible with :c:type:`void*`)
|
||||
function is called with *anything* (which should be compatible with :c:expr:`void*`)
|
||||
as its argument and should return a "new" Python object, or ``NULL`` if an
|
||||
error occurred.
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
|
|||
For :term:`contiguous` arrays, the value points to the beginning of
|
||||
the memory block.
|
||||
|
||||
.. c:member:: void *obj
|
||||
.. c:member:: PyObject *obj
|
||||
|
||||
A new reference to the exporting object. The reference is owned by
|
||||
the consumer and automatically decremented and set to ``NULL`` by
|
||||
|
|
@ -470,27 +470,27 @@ Buffer-related functions
|
|||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char order)
|
||||
.. c:function:: int PyBuffer_IsContiguous(const Py_buffer *view, char order)
|
||||
|
||||
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. This function always succeeds.
|
||||
|
||||
|
||||
.. c:function:: void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
|
||||
.. c:function:: void* PyBuffer_GetPointer(const Py_buffer *view, const Py_ssize_t *indices)
|
||||
|
||||
Get the memory area pointed to by the *indices* inside the given *view*.
|
||||
*indices* must point to an array of ``view->ndim`` indices.
|
||||
|
||||
|
||||
.. c:function:: int PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
|
||||
.. c:function:: int PyBuffer_FromContiguous(const Py_buffer *view, const void *buf, Py_ssize_t len, char fort)
|
||||
|
||||
Copy contiguous *len* bytes from *buf* to *view*.
|
||||
*fort* can be ``'C'`` or ``'F'`` (for C-style or Fortran-style ordering).
|
||||
``0`` is returned on success, ``-1`` on error.
|
||||
|
||||
|
||||
.. c:function:: int PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
|
||||
.. c:function:: int PyBuffer_ToContiguous(void *buf, const Py_buffer *src, Py_ssize_t len, char order)
|
||||
|
||||
Copy *len* bytes from *src* to its contiguous representation in *buf*.
|
||||
*order* can be ``'C'`` or ``'F'`` or ``'A'`` (for C-style or Fortran-style
|
||||
|
|
@ -499,6 +499,13 @@ Buffer-related functions
|
|||
This function fails if *len* != *src->len*.
|
||||
|
||||
|
||||
.. c:function:: int PyObject_CopyData(Py_buffer *dest, Py_buffer *src)
|
||||
|
||||
Copy data from *src* to *dest* buffer. Can convert between C-style and
|
||||
or Fortran-style buffers.
|
||||
|
||||
``0`` is returned on success, ``-1`` on error.
|
||||
|
||||
.. c:function:: void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, int itemsize, char order)
|
||||
|
||||
Fill the *strides* array with byte-strides of a :term:`contiguous` (C-style if
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ Direct API functions
|
|||
Return a new bytearray object from any object, *o*, that implements the
|
||||
:ref:`buffer protocol <bufferobjects>`.
|
||||
|
||||
.. XXX expand about the buffer protocol, at least somewhere
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len)
|
||||
|
||||
|
|
@ -79,9 +77,9 @@ These macros trade safety for speed and they don't check pointers.
|
|||
|
||||
.. c:function:: char* PyByteArray_AS_STRING(PyObject *bytearray)
|
||||
|
||||
Macro version of :c:func:`PyByteArray_AsString`.
|
||||
Similar to :c:func:`PyByteArray_AsString`, but without error checking.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t PyByteArray_GET_SIZE(PyObject *bytearray)
|
||||
|
||||
Macro version of :c:func:`PyByteArray_Size`.
|
||||
Similar to :c:func:`PyByteArray_Size`, but without error checking.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
Bytes Objects
|
||||
-------------
|
||||
|
||||
These functions raise :exc:`TypeError` when expecting a bytes parameter and are
|
||||
These functions raise :exc:`TypeError` when expecting a bytes parameter and
|
||||
called with a non-bytes parameter.
|
||||
|
||||
.. index:: object: bytes
|
||||
|
|
@ -58,9 +58,6 @@ called with a non-bytes parameter.
|
|||
|
||||
.. % XXX: This should be exactly the same as the table in PyErr_Format.
|
||||
.. % One should just refer to the other.
|
||||
.. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated
|
||||
.. % because not all compilers support the %z width modifier -- we fake it
|
||||
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
|
||||
|
||||
.. tabularcolumns:: |l|l|L|
|
||||
|
||||
|
|
@ -84,8 +81,8 @@ called with a non-bytes parameter.
|
|||
| :attr:`%lu` | unsigned long | Equivalent to |
|
||||
| | | ``printf("%lu")``. [1]_ |
|
||||
+-------------------+---------------+--------------------------------+
|
||||
| :attr:`%zd` | Py_ssize_t | Equivalent to |
|
||||
| | | ``printf("%zd")``. [1]_ |
|
||||
| :attr:`%zd` | :c:type:`\ | Equivalent to |
|
||||
| | Py_ssize_t` | ``printf("%zd")``. [1]_ |
|
||||
+-------------------+---------------+--------------------------------+
|
||||
| :attr:`%zu` | size_t | Equivalent to |
|
||||
| | | ``printf("%zu")``. [1]_ |
|
||||
|
|
@ -134,7 +131,7 @@ called with a non-bytes parameter.
|
|||
|
||||
.. c:function:: Py_ssize_t PyBytes_GET_SIZE(PyObject *o)
|
||||
|
||||
Macro form of :c:func:`PyBytes_Size` but without error checking.
|
||||
Similar to :c:func:`PyBytes_Size`, but without error checking.
|
||||
|
||||
|
||||
.. c:function:: char* PyBytes_AsString(PyObject *o)
|
||||
|
|
@ -151,7 +148,7 @@ called with a non-bytes parameter.
|
|||
|
||||
.. c:function:: char* PyBytes_AS_STRING(PyObject *string)
|
||||
|
||||
Macro form of :c:func:`PyBytes_AsString` but without error checking.
|
||||
Similar to :c:func:`PyBytes_AsString`, but without error checking.
|
||||
|
||||
|
||||
.. c:function:: int PyBytes_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ This convention is not only used by *tp_call*:
|
|||
:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_init`
|
||||
also pass arguments this way.
|
||||
|
||||
To call an object, use :c:func:`PyObject_Call` or other
|
||||
To call an object, use :c:func:`PyObject_Call` or another
|
||||
:ref:`call API <capi-call>`.
|
||||
|
||||
|
||||
|
|
@ -57,6 +57,15 @@ This bears repeating:
|
|||
A class supporting vectorcall **must** also implement
|
||||
:c:member:`~PyTypeObject.tp_call` with the same semantics.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class
|
||||
when the class's :py:meth:`~object.__call__` method is reassigned.
|
||||
(This internally sets :c:member:`~PyTypeObject.tp_call` only, and thus
|
||||
may make it behave differently than the vectorcall function.)
|
||||
In earlier Python versions, vectorcall should only be used with
|
||||
:const:`immutable <Py_TPFLAGS_IMMUTABLETYPE>` or static types.
|
||||
|
||||
A class should not implement vectorcall if that would be slower
|
||||
than *tp_call*. For example, if the callee needs to convert
|
||||
the arguments to an args tuple and kwargs dict anyway, then there is no point
|
||||
|
|
@ -84,7 +93,7 @@ This is a pointer to a function with the following signature:
|
|||
and they must be unique.
|
||||
If there are no keyword arguments, then *kwnames* can instead be *NULL*.
|
||||
|
||||
.. c:macro:: PY_VECTORCALL_ARGUMENTS_OFFSET
|
||||
.. data:: PY_VECTORCALL_ARGUMENTS_OFFSET
|
||||
|
||||
If this flag is set in a vectorcall *nargsf* argument, the callee is allowed
|
||||
to temporarily change ``args[-1]``. In other words, *args* points to
|
||||
|
|
@ -144,8 +153,6 @@ Vectorcall Support API
|
|||
However, the function ``PyVectorcall_NARGS`` should be used to allow
|
||||
for future extensions.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. c:function:: vectorcallfunc PyVectorcall_Function(PyObject *op)
|
||||
|
|
@ -158,8 +165,6 @@ Vectorcall Support API
|
|||
This is mostly useful to check whether or not *op* supports vectorcall,
|
||||
which can be done by checking ``PyVectorcall_Function(op) != NULL``.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. c:function:: PyObject* PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)
|
||||
|
|
@ -172,8 +177,6 @@ Vectorcall Support API
|
|||
It does not check the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag
|
||||
and it does not fall back to ``tp_call``.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
|
||||
|
|
@ -256,8 +259,6 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
|
|
@ -283,7 +284,7 @@ please see individual documentation for details.
|
|||
|
||||
This is the equivalent of the Python expression: ``callable(*args)``.
|
||||
|
||||
Note that if you only pass :c:type:`PyObject *` args,
|
||||
Note that if you only pass :c:expr:`PyObject *` args,
|
||||
:c:func:`PyObject_CallFunctionObjArgs` is a faster alternative.
|
||||
|
||||
.. versionchanged:: 3.4
|
||||
|
|
@ -304,7 +305,7 @@ please see individual documentation for details.
|
|||
This is the equivalent of the Python expression:
|
||||
``obj.name(arg1, arg2, ...)``.
|
||||
|
||||
Note that if you only pass :c:type:`PyObject *` args,
|
||||
Note that if you only pass :c:expr:`PyObject *` args,
|
||||
:c:func:`PyObject_CallMethodObjArgs` is a faster alternative.
|
||||
|
||||
.. versionchanged:: 3.4
|
||||
|
|
@ -314,7 +315,7 @@ please see individual documentation for details.
|
|||
.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...)
|
||||
|
||||
Call a callable Python object *callable*, with a variable number of
|
||||
:c:type:`PyObject *` arguments. The arguments are provided as a variable number
|
||||
:c:expr:`PyObject *` arguments. The arguments are provided as a variable number
|
||||
of parameters followed by *NULL*.
|
||||
|
||||
Return the result of the call on success, or raise an exception and return
|
||||
|
|
@ -328,7 +329,7 @@ please see individual documentation for details.
|
|||
|
||||
Call a method of the Python object *obj*, where the name of the method is given as a
|
||||
Python string object in *name*. It is called with a variable number of
|
||||
:c:type:`PyObject *` arguments. The arguments are provided as a variable number
|
||||
:c:expr:`PyObject *` arguments. The arguments are provided as a variable number
|
||||
of parameters followed by *NULL*.
|
||||
|
||||
Return the result of the call on success, or raise an exception and return
|
||||
|
|
@ -343,8 +344,6 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
|
|
@ -357,8 +356,6 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
|
|
@ -372,8 +369,6 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. c:function:: PyObject* PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)
|
||||
|
|
@ -388,8 +383,6 @@ please see individual documentation for details.
|
|||
already has a dictionary ready to use for the keyword arguments,
|
||||
but not a tuple for the positional arguments.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. c:function:: PyObject* PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||
|
|
@ -410,8 +403,6 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
|
|||
.. c:type:: PyCapsule
|
||||
|
||||
This subtype of :c:type:`PyObject` represents an opaque value, useful for C
|
||||
extension modules who need to pass an opaque value (as a :c:type:`void*`
|
||||
extension modules who need to pass an opaque value (as a :c:expr:`void*`
|
||||
pointer) through Python code to other C code. It is often used to make a C
|
||||
function pointer defined in one module available to other modules, so the
|
||||
regular import mechanism can be used to access C APIs defined in dynamically
|
||||
|
|
@ -103,13 +103,14 @@ Refer to :ref:`using-capsules` for more information on using these objects.
|
|||
Import a pointer to a C object from a capsule attribute in a module. The
|
||||
*name* parameter should specify the full name to the attribute, as in
|
||||
``module.attribute``. The *name* stored in the capsule must match this
|
||||
string exactly. If *no_block* is true, import the module without blocking
|
||||
(using :c:func:`PyImport_ImportModuleNoBlock`). If *no_block* is false,
|
||||
import the module conventionally (using :c:func:`PyImport_ImportModule`).
|
||||
string exactly.
|
||||
|
||||
Return the capsule's internal *pointer* on success. On failure, set an
|
||||
exception and return ``NULL``.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
*no_block* has no effect anymore.
|
||||
|
||||
|
||||
.. c:function:: int PyCapsule_IsValid(PyObject *capsule, const char *name)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
.. highlight:: c
|
||||
|
||||
.. _codeobjects:
|
||||
|
||||
.. index:: object; code, code object
|
||||
|
||||
.. _codeobjects:
|
||||
|
||||
Code Objects
|
||||
------------
|
||||
|
||||
|
|
@ -33,24 +33,33 @@ bound into a function.
|
|||
|
||||
Return the number of free variables in *co*.
|
||||
|
||||
.. c:function:: PyCodeObject* PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)
|
||||
.. c:function:: PyCodeObject* PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
|
||||
|
||||
Return a new code object. If you need a dummy code object to create a frame,
|
||||
use :c:func:`PyCode_NewEmpty` instead. Calling :c:func:`PyCode_New` directly
|
||||
can bind you to a precise Python version since the definition of the bytecode
|
||||
changes often.
|
||||
will bind you to a precise Python version since the definition of the bytecode
|
||||
changes often. The many arguments of this function are inter-dependent in complex
|
||||
ways, meaning that subtle changes to values are likely to result in incorrect
|
||||
execution or VM crashes. Use this function only with extreme care.
|
||||
|
||||
.. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)
|
||||
.. versionchanged:: 3.11
|
||||
Added ``exceptiontable`` parameter.
|
||||
|
||||
.. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
|
||||
|
||||
Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positional-only arguments.
|
||||
The same caveats that apply to ``PyCode_New`` also apply to this function.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Added ``exceptiontable`` parameter.
|
||||
|
||||
.. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
|
||||
|
||||
Return a new empty code object with the specified filename,
|
||||
function name, and first line number. It is illegal to
|
||||
:func:`exec` or :func:`eval` the resulting code object.
|
||||
function name, and first line number. The resulting code
|
||||
object will raise an ``Exception`` if executed.
|
||||
|
||||
.. c:function:: int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)
|
||||
|
||||
|
|
@ -58,7 +67,7 @@ bound into a function.
|
|||
If you just need the line number of a frame, use :c:func:`PyFrame_GetLineNumber` instead.
|
||||
|
||||
For efficiently iterating over the line numbers in a code object, use `the API described in PEP 626
|
||||
<https://www.python.org/dev/peps/pep-0626/#out-of-process-debuggers-and-profilers>`_.
|
||||
<https://peps.python.org/pep-0626/#out-of-process-debuggers-and-profilers>`_.
|
||||
|
||||
.. c:function:: int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)
|
||||
|
||||
|
|
@ -67,3 +76,90 @@ bound into a function.
|
|||
information is not available for any particular element.
|
||||
|
||||
Returns ``1`` if the function succeeds and 0 otherwise.
|
||||
|
||||
.. c:function:: PyObject* PyCode_GetCode(PyCodeObject *co)
|
||||
|
||||
Equivalent to the Python code ``getattr(co, 'co_code')``.
|
||||
Returns a strong reference to a :c:type:`PyBytesObject` representing the
|
||||
bytecode in a code object. On error, ``NULL`` is returned and an exception
|
||||
is raised.
|
||||
|
||||
This ``PyBytesObject`` may be created on-demand by the interpreter and does
|
||||
not necessarily represent the bytecode actually executed by CPython. The
|
||||
primary use case for this function is debuggers and profilers.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:function:: PyObject* PyCode_GetVarnames(PyCodeObject *co)
|
||||
|
||||
Equivalent to the Python code ``getattr(co, 'co_varnames')``.
|
||||
Returns a new reference to a :c:type:`PyTupleObject` containing the names of
|
||||
the local variables. On error, ``NULL`` is returned and an exception
|
||||
is raised.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:function:: PyObject* PyCode_GetCellvars(PyCodeObject *co)
|
||||
|
||||
Equivalent to the Python code ``getattr(co, 'co_cellvars')``.
|
||||
Returns a new reference to a :c:type:`PyTupleObject` containing the names of
|
||||
the local variables that are referenced by nested functions. On error, ``NULL``
|
||||
is returned and an exception is raised.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:function:: PyObject* PyCode_GetFreevars(PyCodeObject *co)
|
||||
|
||||
Equivalent to the Python code ``getattr(co, 'co_freevars')``.
|
||||
Returns a new reference to a :c:type:`PyTupleObject` containing the names of
|
||||
the free variables. On error, ``NULL`` is returned and an exception is raised.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:function:: int PyCode_AddWatcher(PyCode_WatchCallback callback)
|
||||
|
||||
Register *callback* as a code object watcher for the current interpreter.
|
||||
Return an ID which may be passed to :c:func:`PyCode_ClearWatcher`.
|
||||
In case of error (e.g. no more watcher IDs available),
|
||||
return ``-1`` and set an exception.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:function:: int PyCode_ClearWatcher(int watcher_id)
|
||||
|
||||
Clear watcher identified by *watcher_id* previously returned from
|
||||
:c:func:`PyCode_AddWatcher` for the current interpreter.
|
||||
Return ``0`` on success, or ``-1`` and set an exception on error
|
||||
(e.g. if the given *watcher_id* was never registered.)
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:type:: PyCodeEvent
|
||||
|
||||
Enumeration of possible code object watcher events:
|
||||
- ``PY_CODE_EVENT_CREATE``
|
||||
- ``PY_CODE_EVENT_DESTROY``
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:type:: int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject* co)
|
||||
|
||||
Type of a code object watcher callback function.
|
||||
|
||||
If *event* is ``PY_CODE_EVENT_CREATE``, then the callback is invoked
|
||||
after `co` has been fully initialized. Otherwise, the callback is invoked
|
||||
before the destruction of *co* takes place, so the prior state of *co*
|
||||
can be inspected.
|
||||
|
||||
Users of this API should not rely on internal runtime implementation
|
||||
details. Such details may include, but are not limited to, the exact
|
||||
order and timing of creation and destruction of code objects. While
|
||||
changes in these details may result in differences observable by watchers
|
||||
(including whether a callback is invoked or not), it does not change
|
||||
the semantics of the Python code being executed.
|
||||
|
||||
If the callback returns with an exception set, it must return ``-1``; this
|
||||
exception will be printed as an unraisable exception using
|
||||
:c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
|
|
|||
|
|
@ -115,12 +115,12 @@ Complex Numbers as Python Objects
|
|||
|
||||
.. c:function:: double PyComplex_RealAsDouble(PyObject *op)
|
||||
|
||||
Return the real part of *op* as a C :c:type:`double`.
|
||||
Return the real part of *op* as a C :c:expr:`double`.
|
||||
|
||||
|
||||
.. c:function:: double PyComplex_ImagAsDouble(PyObject *op)
|
||||
|
||||
Return the imaginary part of *op* as a C :c:type:`double`.
|
||||
Return the imaginary part of *op* as a C :c:expr:`double`.
|
||||
|
||||
|
||||
.. c:function:: Py_complex PyComplex_AsCComplex(PyObject *op)
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ Other Objects
|
|||
memoryview.rst
|
||||
weakref.rst
|
||||
capsule.rst
|
||||
frame.rst
|
||||
gen.rst
|
||||
coro.rst
|
||||
contextvars.rst
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ not.
|
|||
The wrappers ensure that ``str[size-1]`` is always ``'\0'`` upon return. They
|
||||
never write more than *size* bytes (including the trailing ``'\0'``) into str.
|
||||
Both functions require that ``str != NULL``, ``size > 0``, ``format != NULL``
|
||||
and ``size < INT_MAX``.
|
||||
and ``size < INT_MAX``. Note that this means there is no equivalent to the C99
|
||||
``n = snprintf(NULL, 0, ...)`` which would determine the necessary buffer size.
|
||||
|
||||
The return value (*rv*) for these functions should be interpreted as follows:
|
||||
|
||||
|
|
@ -49,7 +50,7 @@ The following functions provide locale-independent string to number conversions.
|
|||
|
||||
.. c:function:: double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)
|
||||
|
||||
Convert a string ``s`` to a :c:type:`double`, raising a Python
|
||||
Convert a string ``s`` to a :c:expr:`double`, raising a Python
|
||||
exception on failure. The set of accepted strings corresponds to
|
||||
the set of strings accepted by Python's :func:`float` constructor,
|
||||
except that ``s`` must not have leading or trailing whitespace.
|
||||
|
|
@ -83,7 +84,7 @@ The following functions provide locale-independent string to number conversions.
|
|||
|
||||
.. c:function:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype)
|
||||
|
||||
Convert a :c:type:`double` *val* to a string using supplied
|
||||
Convert a :c:expr:`double` *val* to a string using supplied
|
||||
*format_code*, *precision*, and *flags*.
|
||||
|
||||
*format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``,
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ Macros to create objects:
|
|||
resulting number of microseconds and seconds lie in the ranges documented for
|
||||
:class:`datetime.timedelta` objects.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyTimeZone_FromOffset(PyDateTime_DeltaType* offset)
|
||||
|
||||
Return a :class:`datetime.timezone` object with an unnamed fixed offset
|
||||
|
|
@ -139,6 +140,7 @@ Macros to create objects:
|
|||
|
||||
.. versionadded:: 3.7
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyTimeZone_FromOffsetAndName(PyDateTime_DeltaType* offset, PyUnicode* name)
|
||||
|
||||
Return a :class:`datetime.timezone` object with a fixed offset represented
|
||||
|
|
@ -190,12 +192,21 @@ must not be ``NULL``, and the type is not checked:
|
|||
|
||||
Return the microsecond, as an int from 0 through 999999.
|
||||
|
||||
|
||||
.. c:function:: int PyDateTime_DATE_GET_FOLD(PyDateTime_DateTime *o)
|
||||
|
||||
Return the fold, as an int from 0 through 1.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyDateTime_DATE_GET_TZINFO(PyDateTime_DateTime *o)
|
||||
|
||||
Return the tzinfo (which may be ``None``).
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
|
||||
Macros to extract fields from time objects. The argument must be an instance of
|
||||
:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``,
|
||||
and the type is not checked:
|
||||
|
|
@ -219,6 +230,14 @@ and the type is not checked:
|
|||
|
||||
Return the microsecond, as an int from 0 through 999999.
|
||||
|
||||
|
||||
.. c:function:: int PyDateTime_TIME_GET_FOLD(PyDateTime_Time *o)
|
||||
|
||||
Return the fold, as an int from 0 through 1.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyDateTime_TIME_GET_TZINFO(PyDateTime_Time *o)
|
||||
|
||||
Return the tzinfo (which may be ``None``).
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ Dictionary Objects
|
|||
.. index:: single: PyUnicode_FromString()
|
||||
|
||||
Insert *val* into the dictionary *p* using *key* as a key. *key* should
|
||||
be a :c:type:`const char*`. The key object is created using
|
||||
be a :c:expr:`const char*`. The key object is created using
|
||||
``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on
|
||||
failure. This function *does not* steal a reference to *val*.
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ Dictionary Objects
|
|||
.. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key)
|
||||
|
||||
This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a
|
||||
:c:type:`const char*`, rather than a :c:type:`PyObject*`.
|
||||
:c:expr:`const char*`, rather than a :c:expr:`PyObject*`.
|
||||
|
||||
Note that exceptions which occur while calling :meth:`__hash__` and
|
||||
:meth:`__eq__` methods and creating a temporary string object
|
||||
|
|
@ -167,7 +167,7 @@ Dictionary Objects
|
|||
prior to the first call to this function to start the iteration; the
|
||||
function returns true for each pair in the dictionary, and false once all
|
||||
pairs have been reported. The parameters *pkey* and *pvalue* should either
|
||||
point to :c:type:`PyObject*` variables that will be filled in with each key
|
||||
point to :c:expr:`PyObject*` variables that will be filled in with each key
|
||||
and value, respectively, or may be ``NULL``. Any references returned through
|
||||
them are borrowed. *ppos* should not be altered during iteration. Its
|
||||
value represents offsets within the internal dictionary structure, and
|
||||
|
|
@ -238,3 +238,73 @@ Dictionary Objects
|
|||
for key, value in seq2:
|
||||
if override or key not in a:
|
||||
a[key] = value
|
||||
|
||||
.. c:function:: int PyDict_AddWatcher(PyDict_WatchCallback callback)
|
||||
|
||||
Register *callback* as a dictionary watcher. Return a non-negative integer
|
||||
id which must be passed to future calls to :c:func:`PyDict_Watch`. In case
|
||||
of error (e.g. no more watcher IDs available), return ``-1`` and set an
|
||||
exception.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:function:: int PyDict_ClearWatcher(int watcher_id)
|
||||
|
||||
Clear watcher identified by *watcher_id* previously returned from
|
||||
:c:func:`PyDict_AddWatcher`. Return ``0`` on success, ``-1`` on error (e.g.
|
||||
if the given *watcher_id* was never registered.)
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:function:: int PyDict_Watch(int watcher_id, PyObject *dict)
|
||||
|
||||
Mark dictionary *dict* as watched. The callback granted *watcher_id* by
|
||||
:c:func:`PyDict_AddWatcher` will be called when *dict* is modified or
|
||||
deallocated. Return ``0`` on success or ``-1`` on error.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:function:: int PyDict_Unwatch(int watcher_id, PyObject *dict)
|
||||
|
||||
Mark dictionary *dict* as no longer watched. The callback granted
|
||||
*watcher_id* by :c:func:`PyDict_AddWatcher` will no longer be called when
|
||||
*dict* is modified or deallocated. The dict must previously have been
|
||||
watched by this watcher. Return ``0`` on success or ``-1`` on error.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:type:: PyDict_WatchEvent
|
||||
|
||||
Enumeration of possible dictionary watcher events: ``PyDict_EVENT_ADDED``,
|
||||
``PyDict_EVENT_MODIFIED``, ``PyDict_EVENT_DELETED``, ``PyDict_EVENT_CLONED``,
|
||||
``PyDict_EVENT_CLEARED``, or ``PyDict_EVENT_DEALLOCATED``.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:type:: int (*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value)
|
||||
|
||||
Type of a dict watcher callback function.
|
||||
|
||||
If *event* is ``PyDict_EVENT_CLEARED`` or ``PyDict_EVENT_DEALLOCATED``, both
|
||||
*key* and *new_value* will be ``NULL``. If *event* is ``PyDict_EVENT_ADDED``
|
||||
or ``PyDict_EVENT_MODIFIED``, *new_value* will be the new value for *key*.
|
||||
If *event* is ``PyDict_EVENT_DELETED``, *key* is being deleted from the
|
||||
dictionary and *new_value* will be ``NULL``.
|
||||
|
||||
``PyDict_EVENT_CLONED`` occurs when *dict* was previously empty and another
|
||||
dict is merged into it. To maintain efficiency of this operation, per-key
|
||||
``PyDict_EVENT_ADDED`` events are not issued in this case; instead a
|
||||
single ``PyDict_EVENT_CLONED`` is issued, and *key* will be the source
|
||||
dictionary.
|
||||
|
||||
The callback may inspect but must not modify *dict*; doing so could have
|
||||
unpredictable effects, including infinite recursion.
|
||||
|
||||
Callbacks occur before the notified modification to *dict* takes place, so
|
||||
the prior state of *dict* can be inspected.
|
||||
|
||||
If the callback returns with an exception set, it must return ``-1``; this
|
||||
exception will be printed as an unraisable exception using
|
||||
:c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ there is a global indicator (per thread) of the last error that occurred. Most
|
|||
C API functions don't clear this on success, but will set it to indicate the
|
||||
cause of the error on failure. Most C API functions also return an error
|
||||
indicator, usually ``NULL`` if they are supposed to return a pointer, or ``-1``
|
||||
if they return an integer (exception: the :c:func:`PyArg_\*` functions
|
||||
if they return an integer (exception: the ``PyArg_*`` functions
|
||||
return ``1`` for success and ``0`` for failure).
|
||||
|
||||
Concretely, the error indicator consists of three object pointers: the
|
||||
|
|
@ -189,7 +189,7 @@ For convenience, some of these functions will always return a
|
|||
.. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr)
|
||||
|
||||
This is a convenience function to raise :exc:`WindowsError`. If called with
|
||||
*ierr* of :c:data:`0`, the error code returned by a call to :c:func:`GetLastError`
|
||||
*ierr* of ``0``, the error code returned by a call to :c:func:`GetLastError`
|
||||
is used instead. It calls the Win32 function :c:func:`FormatMessage` to retrieve
|
||||
the Windows description of error code given by *ierr* or :c:func:`GetLastError`,
|
||||
then it constructs a tuple object whose first item is the *ierr* value and whose
|
||||
|
|
@ -253,6 +253,14 @@ For convenience, some of these functions will always return a
|
|||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
|
||||
|
||||
Much like :c:func:`PyErr_SetImportError` but this function allows for
|
||||
specifying a subclass of :exc:`ImportError` to raise.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
|
||||
.. c:function:: void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
|
||||
|
||||
Set file, line, and offset information for the current exception. If the
|
||||
|
|
@ -273,7 +281,7 @@ For convenience, some of these functions will always return a
|
|||
|
||||
.. c:function:: void PyErr_SyntaxLocation(const char *filename, int lineno)
|
||||
|
||||
Like :c:func:`PyErr_SyntaxLocationEx`, but the col_offset parameter is
|
||||
Like :c:func:`PyErr_SyntaxLocationEx`, but the *col_offset* parameter is
|
||||
omitted.
|
||||
|
||||
|
||||
|
|
@ -320,19 +328,12 @@ an error value).
|
|||
:mod:`warnings` module and the :option:`-W` option in the command line
|
||||
documentation. There is no C API for warning control.
|
||||
|
||||
.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
|
||||
|
||||
Much like :c:func:`PyErr_SetImportError` but this function allows for
|
||||
specifying a subclass of :exc:`ImportError` to raise.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
|
||||
.. c:function:: int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry)
|
||||
|
||||
Issue a warning message with explicit control over all warning attributes. This
|
||||
is a straightforward wrapper around the Python function
|
||||
:func:`warnings.warn_explicit`, see there for more information. The *module*
|
||||
:func:`warnings.warn_explicit`; see there for more information. The *module*
|
||||
and *registry* arguments may be set to ``NULL`` to get the default effect
|
||||
described there.
|
||||
|
||||
|
|
@ -369,7 +370,7 @@ Querying the error indicator
|
|||
.. c:function:: PyObject* PyErr_Occurred()
|
||||
|
||||
Test whether the error indicator is set. If set, return the exception *type*
|
||||
(the first argument to the last call to one of the :c:func:`PyErr_Set\*`
|
||||
(the first argument to the last call to one of the ``PyErr_Set*``
|
||||
functions or to :c:func:`PyErr_Restore`). If not set, return ``NULL``. You do not
|
||||
own a reference to the return value, so you do not need to :c:func:`Py_DECREF`
|
||||
it.
|
||||
|
|
@ -440,7 +441,7 @@ Querying the error indicator
|
|||
error indicator.
|
||||
|
||||
|
||||
.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)
|
||||
.. c:function:: void PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
|
||||
|
||||
Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below
|
||||
can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is
|
||||
|
|
@ -459,12 +460,46 @@ Querying the error indicator
|
|||
}
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyErr_GetHandledException(void)
|
||||
|
||||
Retrieve the active exception instance, as would be returned by :func:`sys.exception`.
|
||||
This refers to an exception that was *already caught*, not to an exception that was
|
||||
freshly raised. Returns a new reference to the exception or ``NULL``.
|
||||
Does not modify the interpreter's exception state.
|
||||
|
||||
.. note::
|
||||
|
||||
This function is not normally used by code that wants to handle exceptions.
|
||||
Rather, it can be used when code needs to save and restore the exception
|
||||
state temporarily. Use :c:func:`PyErr_SetHandledException` to restore or
|
||||
clear the exception state.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:function:: void PyErr_SetHandledException(PyObject *exc)
|
||||
|
||||
Set the active exception, as known from ``sys.exception()``. This refers
|
||||
to an exception that was *already caught*, not to an exception that was
|
||||
freshly raised.
|
||||
To clear the exception state, pass ``NULL``.
|
||||
|
||||
.. note::
|
||||
|
||||
This function is not normally used by code that wants to handle exceptions.
|
||||
Rather, it can be used when code needs to save and restore the exception
|
||||
state temporarily. Use :c:func:`PyErr_GetHandledException` to get the exception
|
||||
state.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:function:: void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)
|
||||
|
||||
Retrieve the exception info, as known from ``sys.exc_info()``. This refers
|
||||
to an exception that was *already caught*, not to an exception that was
|
||||
freshly raised. Returns new references for the three objects, any of which
|
||||
may be ``NULL``. Does not modify the exception info state.
|
||||
Retrieve the old-style representation of the exception info, as known from
|
||||
:func:`sys.exc_info`. This refers to an exception that was *already caught*,
|
||||
not to an exception that was freshly raised. Returns new references for the
|
||||
three objects, any of which may be ``NULL``. Does not modify the exception
|
||||
info state. This function is kept for backwards compatibility. Prefer using
|
||||
:c:func:`PyErr_GetHandledException`.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -482,7 +517,8 @@ Querying the error indicator
|
|||
to an exception that was *already caught*, not to an exception that was
|
||||
freshly raised. This function steals the references of the arguments.
|
||||
To clear the exception state, pass ``NULL`` for all three arguments.
|
||||
For general rules about the three arguments, see :c:func:`PyErr_Restore`.
|
||||
This function is kept for backwards compatibility. Prefer using
|
||||
:c:func:`PyErr_SetHandledException`.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -493,6 +529,12 @@ Querying the error indicator
|
|||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
The ``type`` and ``traceback`` arguments are no longer used and
|
||||
can be NULL. The interpreter now derives them from the exception
|
||||
instance (the ``value`` argument). The function still steals
|
||||
references of all three arguments.
|
||||
|
||||
|
||||
Signal Handling
|
||||
===============
|
||||
|
|
@ -806,7 +848,7 @@ Standard Exceptions
|
|||
|
||||
All standard Python exceptions are available as global variables whose names are
|
||||
``PyExc_`` followed by the Python exception name. These have the type
|
||||
:c:type:`PyObject*`; they are all class objects. For completeness, here are all
|
||||
:c:expr:`PyObject*`; they are all class objects. For completeness, here are all
|
||||
the variables:
|
||||
|
||||
.. index::
|
||||
|
|
@ -867,11 +909,11 @@ the variables:
|
|||
+-----------------------------------------+---------------------------------+----------+
|
||||
| C Name | Python Name | Notes |
|
||||
+=========================================+=================================+==========+
|
||||
| :c:data:`PyExc_BaseException` | :exc:`BaseException` | \(1) |
|
||||
| :c:data:`PyExc_BaseException` | :exc:`BaseException` | [1]_ |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_Exception` | :exc:`Exception` | \(1) |
|
||||
| :c:data:`PyExc_Exception` | :exc:`Exception` | [1]_ |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) |
|
||||
| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | [1]_ |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_AssertionError` | :exc:`AssertionError` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
|
|
@ -917,7 +959,7 @@ the variables:
|
|||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) |
|
||||
| :c:data:`PyExc_LookupError` | :exc:`LookupError` | [1]_ |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_MemoryError` | :exc:`MemoryError` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
|
|
@ -929,7 +971,7 @@ the variables:
|
|||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_OSError` | :exc:`OSError` | \(1) |
|
||||
| :c:data:`PyExc_OSError` | :exc:`OSError` | [1]_ |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_OverflowError` | :exc:`OverflowError` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
|
|
@ -939,7 +981,7 @@ the variables:
|
|||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_RecursionError` | :exc:`RecursionError` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) |
|
||||
| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | |
|
||||
+-----------------------------------------+---------------------------------+----------+
|
||||
|
|
@ -1004,7 +1046,7 @@ These are compatibility aliases to :c:data:`PyExc_OSError`:
|
|||
+-------------------------------------+----------+
|
||||
| :c:data:`PyExc_IOError` | |
|
||||
+-------------------------------------+----------+
|
||||
| :c:data:`PyExc_WindowsError` | \(3) |
|
||||
| :c:data:`PyExc_WindowsError` | [2]_ |
|
||||
+-------------------------------------+----------+
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
|
|
@ -1012,10 +1054,10 @@ These are compatibility aliases to :c:data:`PyExc_OSError`:
|
|||
|
||||
Notes:
|
||||
|
||||
(1)
|
||||
.. [1]
|
||||
This is a base class for other standard exceptions.
|
||||
|
||||
(2)
|
||||
.. [2]
|
||||
Only defined on Windows; protect code that uses this by testing that the
|
||||
preprocessor macro ``MS_WINDOWS`` is defined.
|
||||
|
||||
|
|
@ -1026,7 +1068,7 @@ Standard Warning Categories
|
|||
|
||||
All standard Python warning categories are available as global variables whose
|
||||
names are ``PyExc_`` followed by the Python exception name. These have the type
|
||||
:c:type:`PyObject*`; they are all class objects. For completeness, here are all
|
||||
:c:expr:`PyObject*`; they are all class objects. For completeness, here are all
|
||||
the variables:
|
||||
|
||||
.. index::
|
||||
|
|
@ -1045,7 +1087,7 @@ the variables:
|
|||
+------------------------------------------+---------------------------------+----------+
|
||||
| C Name | Python Name | Notes |
|
||||
+==========================================+=================================+==========+
|
||||
| :c:data:`PyExc_Warning` | :exc:`Warning` | \(1) |
|
||||
| :c:data:`PyExc_Warning` | :exc:`Warning` | [3]_ |
|
||||
+------------------------------------------+---------------------------------+----------+
|
||||
| :c:data:`PyExc_BytesWarning` | :exc:`BytesWarning` | |
|
||||
+------------------------------------------+---------------------------------+----------+
|
||||
|
|
@ -1073,5 +1115,5 @@ the variables:
|
|||
|
||||
Notes:
|
||||
|
||||
(1)
|
||||
.. [3]
|
||||
This is a base class for other standard warning categories.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ File Objects
|
|||
.. index:: object: file
|
||||
|
||||
These APIs are a minimal emulation of the Python 2 C API for built-in file
|
||||
objects, which used to rely on the buffered I/O (:c:type:`FILE*`) support
|
||||
objects, which used to rely on the buffered I/O (:c:expr:`FILE*`) support
|
||||
from the C standard library. In Python 3, files and streams use the new
|
||||
:mod:`io` module, which defines several layers over the low-level unbuffered
|
||||
I/O of the operating system. The functions described below are
|
||||
|
|
@ -38,7 +38,7 @@ the :mod:`io` APIs instead.
|
|||
|
||||
.. c:function:: int PyObject_AsFileDescriptor(PyObject *p)
|
||||
|
||||
Return the file descriptor associated with *p* as an :c:type:`int`. If the
|
||||
Return the file descriptor associated with *p* as an :c:expr:`int`. If the
|
||||
object is an integer, its value is returned. If not, the
|
||||
object's :meth:`~io.IOBase.fileno` method is called if it exists; the
|
||||
method must return an integer, which is returned as the file descriptor
|
||||
|
|
@ -65,7 +65,7 @@ the :mod:`io` APIs instead.
|
|||
Overrides the normal behavior of :func:`io.open_code` to pass its parameter
|
||||
through the provided handler.
|
||||
|
||||
The handler is a function of type :c:type:`PyObject *(\*)(PyObject *path,
|
||||
The handler is a function of type :c:expr:`PyObject *(\*)(PyObject *path,
|
||||
void *userData)`, where *path* is guaranteed to be :c:type:`PyUnicodeObject`.
|
||||
|
||||
The *userData* pointer is passed into the hook function. Since hook
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Floating Point Objects
|
|||
|
||||
.. c:function:: double PyFloat_AsDouble(PyObject *pyfloat)
|
||||
|
||||
Return a C :c:type:`double` representation of the contents of *pyfloat*. If
|
||||
Return a C :c:expr:`double` representation of the contents of *pyfloat*. If
|
||||
*pyfloat* is not a Python floating point object but has a :meth:`__float__`
|
||||
method, this method will first be called to convert *pyfloat* into a float.
|
||||
If ``__float__()`` is not defined then it falls back to :meth:`__index__`.
|
||||
|
|
@ -57,7 +57,7 @@ Floating Point Objects
|
|||
|
||||
.. c:function:: double PyFloat_AS_DOUBLE(PyObject *pyfloat)
|
||||
|
||||
Return a C :c:type:`double` representation of the contents of *pyfloat*, but
|
||||
Return a C :c:expr:`double` representation of the contents of *pyfloat*, but
|
||||
without error checking.
|
||||
|
||||
|
||||
|
|
@ -70,9 +70,95 @@ Floating Point Objects
|
|||
|
||||
.. c:function:: double PyFloat_GetMax()
|
||||
|
||||
Return the maximum representable finite float *DBL_MAX* as C :c:type:`double`.
|
||||
Return the maximum representable finite float *DBL_MAX* as C :c:expr:`double`.
|
||||
|
||||
|
||||
.. c:function:: double PyFloat_GetMin()
|
||||
|
||||
Return the minimum normalized positive float *DBL_MIN* as C :c:type:`double`.
|
||||
Return the minimum normalized positive float *DBL_MIN* as C :c:expr:`double`.
|
||||
|
||||
|
||||
Pack and Unpack functions
|
||||
=========================
|
||||
|
||||
The pack and unpack functions provide an efficient platform-independent way to
|
||||
store floating-point values as byte strings. The Pack routines produce a bytes
|
||||
string from a C :c:expr:`double`, and the Unpack routines produce a C
|
||||
:c:expr:`double` from such a bytes string. The suffix (2, 4 or 8) specifies the
|
||||
number of bytes in the bytes string.
|
||||
|
||||
On platforms that appear to use IEEE 754 formats these functions work by
|
||||
copying bits. On other platforms, the 2-byte format is identical to the IEEE
|
||||
754 binary16 half-precision format, the 4-byte format (32-bit) is identical to
|
||||
the IEEE 754 binary32 single precision format, and the 8-byte format to the
|
||||
IEEE 754 binary64 double precision format, although the packing of INFs and
|
||||
NaNs (if such things exist on the platform) isn't handled correctly, and
|
||||
attempting to unpack a bytes string containing an IEEE INF or NaN will raise an
|
||||
exception.
|
||||
|
||||
On non-IEEE platforms with more precision, or larger dynamic range, than IEEE
|
||||
754 supports, not all values can be packed; on non-IEEE platforms with less
|
||||
precision, or smaller dynamic range, not all values can be unpacked. What
|
||||
happens in such cases is partly accidental (alas).
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
Pack functions
|
||||
--------------
|
||||
|
||||
The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an
|
||||
:c:expr:`int` argument, non-zero if you want the bytes string in little-endian
|
||||
format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you
|
||||
want big-endian format (exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN`
|
||||
constant can be used to use the native endian: it is equal to ``1`` on big
|
||||
endian processor, or ``0`` on little endian processor.
|
||||
|
||||
Return value: ``0`` if all is OK, ``-1`` if error (and an exception is set,
|
||||
most likely :exc:`OverflowError`).
|
||||
|
||||
There are two problems on non-IEEE platforms:
|
||||
|
||||
* What this does is undefined if *x* is a NaN or infinity.
|
||||
* ``-0.0`` and ``+0.0`` produce the same bytes string.
|
||||
|
||||
.. c:function:: int PyFloat_Pack2(double x, unsigned char *p, int le)
|
||||
|
||||
Pack a C double as the IEEE 754 binary16 half-precision format.
|
||||
|
||||
.. c:function:: int PyFloat_Pack4(double x, unsigned char *p, int le)
|
||||
|
||||
Pack a C double as the IEEE 754 binary32 single precision format.
|
||||
|
||||
.. c:function:: int PyFloat_Pack8(double x, unsigned char *p, int le)
|
||||
|
||||
Pack a C double as the IEEE 754 binary64 double precision format.
|
||||
|
||||
|
||||
Unpack functions
|
||||
----------------
|
||||
|
||||
The unpack routines read 2, 4 or 8 bytes, starting at *p*. *le* is an
|
||||
:c:expr:`int` argument, non-zero if the bytes string is in little-endian format
|
||||
(exponent last, at ``p+1``, ``p+3`` or ``p+6`` and ``p+7``), zero if big-endian
|
||||
(exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` constant can be used to
|
||||
use the native endian: it is equal to ``1`` on big endian processor, or ``0``
|
||||
on little endian processor.
|
||||
|
||||
Return value: The unpacked double. On error, this is ``-1.0`` and
|
||||
:c:func:`PyErr_Occurred` is true (and an exception is set, most likely
|
||||
:exc:`OverflowError`).
|
||||
|
||||
Note that on a non-IEEE platform this will refuse to unpack a bytes string that
|
||||
represents a NaN or infinity.
|
||||
|
||||
.. c:function:: double PyFloat_Unpack2(const unsigned char *p, int le)
|
||||
|
||||
Unpack the IEEE 754 binary16 half-precision format as a C double.
|
||||
|
||||
.. c:function:: double PyFloat_Unpack4(const unsigned char *p, int le)
|
||||
|
||||
Unpack the IEEE 754 binary32 single precision format as a C double.
|
||||
|
||||
.. c:function:: double PyFloat_Unpack8(const unsigned char *p, int le)
|
||||
|
||||
Unpack the IEEE 754 binary64 double precision format as a C double.
|
||||
|
|
|
|||
132
Doc/c-api/frame.rst
Normal file
132
Doc/c-api/frame.rst
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
.. highlight:: c
|
||||
|
||||
Frame Objects
|
||||
-------------
|
||||
|
||||
.. c:type:: PyFrameObject
|
||||
|
||||
The C structure of the objects used to describe frame objects.
|
||||
|
||||
There are no public members in this structure.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
The members of this structure were removed from the public C API.
|
||||
Refer to the :ref:`What's New entry <pyframeobject-3.11-hiding>`
|
||||
for details.
|
||||
|
||||
The :c:func:`PyEval_GetFrame` and :c:func:`PyThreadState_GetFrame` functions
|
||||
can be used to get a frame object.
|
||||
|
||||
See also :ref:`Reflection <reflection>`.
|
||||
|
||||
.. c:var:: PyTypeObject PyFrame_Type
|
||||
|
||||
The type of frame objects.
|
||||
It is the same object as :py:class:`types.FrameType` in the Python layer.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
|
||||
Previously, this type was only available after including
|
||||
``<frameobject.h>``.
|
||||
|
||||
.. c:function:: int PyFrame_Check(PyObject *obj)
|
||||
|
||||
Return non-zero if *obj* is a frame object.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
|
||||
Previously, this function was only available after including
|
||||
``<frameobject.h>``.
|
||||
|
||||
.. c:function:: PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
|
||||
|
||||
Get the *frame* next outer frame.
|
||||
|
||||
Return a :term:`strong reference`, or ``NULL`` if *frame* has no outer
|
||||
frame.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyFrame_GetBuiltins(PyFrameObject *frame)
|
||||
|
||||
Get the *frame*'s ``f_builtins`` attribute.
|
||||
|
||||
Return a :term:`strong reference`. The result cannot be ``NULL``.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. c:function:: PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
|
||||
|
||||
Get the *frame* code.
|
||||
|
||||
Return a :term:`strong reference`.
|
||||
|
||||
The result (frame code) cannot be ``NULL``.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyFrame_GetGenerator(PyFrameObject *frame)
|
||||
|
||||
Get the generator, coroutine, or async generator that owns this frame,
|
||||
or ``NULL`` if this frame is not owned by a generator.
|
||||
Does not raise an exception, even if the return value is ``NULL``.
|
||||
|
||||
Return a :term:`strong reference`, or ``NULL``.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyFrame_GetGlobals(PyFrameObject *frame)
|
||||
|
||||
Get the *frame*'s ``f_globals`` attribute.
|
||||
|
||||
Return a :term:`strong reference`. The result cannot be ``NULL``.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. c:function:: int PyFrame_GetLasti(PyFrameObject *frame)
|
||||
|
||||
Get the *frame*'s ``f_lasti`` attribute.
|
||||
|
||||
Returns -1 if ``frame.f_lasti`` is ``None``.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyFrame_GetVar(PyFrameObject *frame, PyObject *name)
|
||||
|
||||
Get the variable *name* of *frame*.
|
||||
|
||||
* Return a :term:`strong reference` to the variable value on success.
|
||||
* Raise :exc:`NameError` and return ``NULL`` if the variable does not exist.
|
||||
* Raise an exception and return ``NULL`` on error.
|
||||
|
||||
*name* type must be a :class:`str`.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyFrame_GetVarString(PyFrameObject *frame, const char *name)
|
||||
|
||||
Similar to :c:func:`PyFrame_GetVar`, but the variable name is a C string
|
||||
encoded in UTF-8.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyFrame_GetLocals(PyFrameObject *frame)
|
||||
|
||||
Get the *frame*'s ``f_locals`` attribute (:class:`dict`).
|
||||
|
||||
Return a :term:`strong reference`.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame)
|
||||
|
||||
Return the line number that *frame* is currently executing.
|
||||
|
|
@ -83,6 +83,15 @@ There are a few functions specific to Python functions.
|
|||
Raises :exc:`SystemError` and returns ``-1`` on failure.
|
||||
|
||||
|
||||
.. c:function:: void PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall)
|
||||
|
||||
Set the vectorcall field of a given function object *func*.
|
||||
|
||||
Warning: extensions using this API must preserve the behavior
|
||||
of the unaltered (default) vectorcall function!
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:function:: PyObject* PyFunction_GetClosure(PyObject *op)
|
||||
|
||||
Return the closure associated with the function object *op*. This can be ``NULL``
|
||||
|
|
@ -109,3 +118,63 @@ There are a few functions specific to Python functions.
|
|||
must be a dictionary or ``Py_None``.
|
||||
|
||||
Raises :exc:`SystemError` and returns ``-1`` on failure.
|
||||
|
||||
|
||||
.. c:function:: int PyFunction_AddWatcher(PyFunction_WatchCallback callback)
|
||||
|
||||
Register *callback* as a function watcher for the current interpreter.
|
||||
Return an ID which may be passed to :c:func:`PyFunction_ClearWatcher`.
|
||||
In case of error (e.g. no more watcher IDs available),
|
||||
return ``-1`` and set an exception.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
.. c:function:: int PyFunction_ClearWatcher(int watcher_id)
|
||||
|
||||
Clear watcher identified by *watcher_id* previously returned from
|
||||
:c:func:`PyFunction_AddWatcher` for the current interpreter.
|
||||
Return ``0`` on success, or ``-1`` and set an exception on error
|
||||
(e.g. if the given *watcher_id* was never registered.)
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
.. c:type:: PyFunction_WatchEvent
|
||||
|
||||
Enumeration of possible function watcher events:
|
||||
- ``PyFunction_EVENT_CREATE``
|
||||
- ``PyFunction_EVENT_DESTROY``
|
||||
- ``PyFunction_EVENT_MODIFY_CODE``
|
||||
- ``PyFunction_EVENT_MODIFY_DEFAULTS``
|
||||
- ``PyFunction_EVENT_MODIFY_KWDEFAULTS``
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
.. c:type:: int (*PyFunction_WatchCallback)(PyFunction_WatchEvent event, PyFunctionObject *func, PyObject *new_value)
|
||||
|
||||
Type of a function watcher callback function.
|
||||
|
||||
If *event* is ``PyFunction_EVENT_CREATE`` or ``PyFunction_EVENT_DESTROY``
|
||||
then *new_value* will be ``NULL``. Otherwise, *new_value* will hold a
|
||||
:term:`borrowed reference` to the new value that is about to be stored in
|
||||
*func* for the attribute that is being modified.
|
||||
|
||||
The callback may inspect but must not modify *func*; doing so could have
|
||||
unpredictable effects, including infinite recursion.
|
||||
|
||||
If *event* is ``PyFunction_EVENT_CREATE``, then the callback is invoked
|
||||
after `func` has been fully initialized. Otherwise, the callback is invoked
|
||||
before the modification to *func* takes place, so the prior state of *func*
|
||||
can be inspected. The runtime is permitted to optimize away the creation of
|
||||
function objects when possible. In such cases no event will be emitted.
|
||||
Although this creates the possitibility of an observable difference of
|
||||
runtime behavior depending on optimization decisions, it does not change
|
||||
the semantics of the Python code being executed.
|
||||
|
||||
If the callback returns with an exception set, it must return ``-1``; this
|
||||
exception will be printed as an unraisable exception using
|
||||
:c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
|
|
|||
|
|
@ -150,6 +150,11 @@ Importing Modules
|
|||
See also :c:func:`PyImport_ExecCodeModuleEx` and
|
||||
:c:func:`PyImport_ExecCodeModuleWithPathnames`.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The setting of :attr:`__cached__` and :attr:`__loader__` is
|
||||
deprecated. See :class:`~importlib.machinery.ModuleSpec` for
|
||||
alternatives.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)
|
||||
|
||||
|
|
@ -167,6 +172,10 @@ Importing Modules
|
|||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
Setting :attr:`__cached__` is deprecated. See
|
||||
:class:`~importlib.machinery.ModuleSpec` for alternatives.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, const char *pathname, const char *cpathname)
|
||||
|
||||
|
|
@ -243,7 +252,7 @@ Importing Modules
|
|||
UTF-8 encoded string instead of a Unicode object.
|
||||
|
||||
|
||||
.. c:type:: struct _frozen
|
||||
.. c:struct:: _frozen
|
||||
|
||||
.. index:: single: freeze utility
|
||||
|
||||
|
|
@ -256,12 +265,16 @@ Importing Modules
|
|||
const char *name;
|
||||
const unsigned char *code;
|
||||
int size;
|
||||
bool is_package;
|
||||
};
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
The new ``is_package`` field indicates whether the module is a package or not.
|
||||
This replaces setting the ``size`` field to a negative value.
|
||||
|
||||
.. c:var:: const struct _frozen* PyImport_FrozenModules
|
||||
|
||||
This pointer is initialized to point to an array of :c:type:`struct _frozen`
|
||||
This pointer is initialized to point to an array of :c:struct:`_frozen`
|
||||
records, terminated by one whose members are all ``NULL`` or zero. When a frozen
|
||||
module is imported, it is searched in this table. Third-party code could play
|
||||
tricks with this to provide a dynamically created collection of frozen modules.
|
||||
|
|
@ -277,7 +290,7 @@ Importing Modules
|
|||
:c:func:`Py_Initialize`.
|
||||
|
||||
|
||||
.. c:type:: struct _inittab
|
||||
.. c:struct:: _inittab
|
||||
|
||||
Structure describing a single entry in the list of built-in modules. Each of
|
||||
these structures gives the name and initialization function for a module built
|
||||
|
|
|
|||
|
|
@ -83,52 +83,93 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
|
|||
|
||||
.. c:var:: int Py_BytesWarningFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.bytes_warning` should be used instead, see :ref:`Python
|
||||
Initialization Configuration <init-config>`.
|
||||
|
||||
Issue a warning when comparing :class:`bytes` or :class:`bytearray` with
|
||||
:class:`str` or :class:`bytes` with :class:`int`. Issue an error if greater
|
||||
or equal to ``2``.
|
||||
|
||||
Set by the :option:`-b` option.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_DebugFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.parser_debug` should be used instead, see :ref:`Python
|
||||
Initialization Configuration <init-config>`.
|
||||
|
||||
Turn on parser debugging output (for expert only, depending on compilation
|
||||
options).
|
||||
|
||||
Set by the :option:`-d` option and the :envvar:`PYTHONDEBUG` environment
|
||||
variable.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_DontWriteBytecodeFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.write_bytecode` should be used instead, see :ref:`Python
|
||||
Initialization Configuration <init-config>`.
|
||||
|
||||
If set to non-zero, Python won't try to write ``.pyc`` files on the
|
||||
import of source modules.
|
||||
|
||||
Set by the :option:`-B` option and the :envvar:`PYTHONDONTWRITEBYTECODE`
|
||||
environment variable.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_FrozenFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.pathconfig_warnings` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Suppress error messages when calculating the module search path in
|
||||
:c:func:`Py_GetPath`.
|
||||
|
||||
Private flag used by ``_freeze_module`` and ``frozenmain`` programs.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_HashRandomizationFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.hash_seed` and :c:member:`PyConfig.use_hash_seed` should
|
||||
be used instead, see :ref:`Python Initialization Configuration
|
||||
<init-config>`.
|
||||
|
||||
Set to ``1`` if the :envvar:`PYTHONHASHSEED` environment variable is set to
|
||||
a non-empty string.
|
||||
|
||||
If the flag is non-zero, read the :envvar:`PYTHONHASHSEED` environment
|
||||
variable to initialize the secret hash seed.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_IgnoreEnvironmentFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.use_environment` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Ignore all :envvar:`PYTHON*` environment variables, e.g.
|
||||
:envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set.
|
||||
|
||||
Set by the :option:`-E` and :option:`-I` options.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_InspectFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.inspect` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
When a script is passed as first argument or the :option:`-c` option is used,
|
||||
enter interactive mode after executing the script or the command, even when
|
||||
:data:`sys.stdin` does not appear to be a terminal.
|
||||
|
|
@ -136,12 +177,24 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
|
|||
Set by the :option:`-i` option and the :envvar:`PYTHONINSPECT` environment
|
||||
variable.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_InteractiveFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.interactive` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Set by the :option:`-i` option.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_IsolatedFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.isolated` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Run Python in isolated mode. In isolated mode :data:`sys.path` contains
|
||||
neither the script's directory nor the user's site-packages directory.
|
||||
|
||||
|
|
@ -149,8 +202,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
|
|||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_LegacyWindowsFSEncodingFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyPreConfig.legacy_windows_fs_encoding` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
If the flag is non-zero, use the ``mbcs`` encoding with ``replace`` error
|
||||
handler, instead of the UTF-8 encoding with ``surrogatepass`` error handler,
|
||||
for the :term:`filesystem encoding and error handler`.
|
||||
|
|
@ -162,8 +221,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
|
|||
|
||||
.. availability:: Windows.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_LegacyWindowsStdioFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.legacy_windows_stdio` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
If the flag is non-zero, use :class:`io.FileIO` instead of
|
||||
:class:`WindowsConsoleIO` for :mod:`sys` standard streams.
|
||||
|
||||
|
|
@ -174,8 +239,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
|
|||
|
||||
.. availability:: Windows.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_NoSiteFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.site_import` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Disable the import of the module :mod:`site` and the site-dependent
|
||||
manipulations of :data:`sys.path` that it entails. Also disable these
|
||||
manipulations if :mod:`site` is explicitly imported later (call
|
||||
|
|
@ -183,36 +254,66 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
|
|||
|
||||
Set by the :option:`-S` option.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_NoUserSiteDirectory
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.user_site_directory` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Don't add the :data:`user site-packages directory <site.USER_SITE>` to
|
||||
:data:`sys.path`.
|
||||
|
||||
Set by the :option:`-s` and :option:`-I` options, and the
|
||||
:envvar:`PYTHONNOUSERSITE` environment variable.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_OptimizeFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.optimization_level` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Set by the :option:`-O` option and the :envvar:`PYTHONOPTIMIZE` environment
|
||||
variable.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_QuietFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.quiet` should be used instead, see :ref:`Python
|
||||
Initialization Configuration <init-config>`.
|
||||
|
||||
Don't display the copyright and version messages even in interactive mode.
|
||||
|
||||
Set by the :option:`-q` option.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_UnbufferedStdioFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.buffered_stdio` should be used instead, see :ref:`Python
|
||||
Initialization Configuration <init-config>`.
|
||||
|
||||
Force the stdout and stderr streams to be unbuffered.
|
||||
|
||||
Set by the :option:`-u` option and the :envvar:`PYTHONUNBUFFERED`
|
||||
environment variable.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
.. c:var:: int Py_VerboseFlag
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.verbose` should be used instead, see :ref:`Python
|
||||
Initialization Configuration <init-config>`.
|
||||
|
||||
Print a message each time a module is initialized, showing the place
|
||||
(filename or built-in module) from which it is loaded. If greater or equal
|
||||
to ``2``, print a message for each file that is checked for when
|
||||
|
|
@ -221,6 +322,8 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
|
|||
Set by the :option:`-v` option and the :envvar:`PYTHONVERBOSE` environment
|
||||
variable.
|
||||
|
||||
.. deprecated:: 3.12
|
||||
|
||||
|
||||
Initializing and finalizing the interpreter
|
||||
===========================================
|
||||
|
|
@ -253,6 +356,9 @@ Initializing and finalizing the interpreter
|
|||
(without calling :c:func:`Py_FinalizeEx` first). There is no return value; it is a
|
||||
fatal error if the initialization fails.
|
||||
|
||||
Use the :c:func:`Py_InitializeFromConfig` function to customize the
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
.. note::
|
||||
On Windows, changes the console mode from ``O_TEXT`` to ``O_BINARY``, which will
|
||||
also affect non-Python uses of the console using the C Runtime.
|
||||
|
|
@ -264,6 +370,9 @@ Initializing and finalizing the interpreter
|
|||
*initsigs* is ``0``, it skips initialization registration of signal handlers, which
|
||||
might be useful when Python is embedded.
|
||||
|
||||
Use the :c:func:`Py_InitializeFromConfig` function to customize the
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
|
||||
.. c:function:: int Py_IsInitialized()
|
||||
|
||||
|
|
@ -376,7 +485,7 @@ Process-wide parameters
|
|||
interpreter will change the contents of this storage.
|
||||
|
||||
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
|
||||
:c:type:`wchar_*` string.
|
||||
:c:expr:`wchar_*` string.
|
||||
|
||||
.. deprecated:: 3.11
|
||||
|
||||
|
|
@ -527,7 +636,7 @@ Process-wide parameters
|
|||
if required after calling :c:func:`Py_Initialize`.
|
||||
|
||||
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
|
||||
:c:type:`wchar_*` string.
|
||||
:c:expr:`wchar_*` string.
|
||||
|
||||
The path argument is copied internally, so the caller may free it after the
|
||||
call completes.
|
||||
|
|
@ -549,10 +658,12 @@ Process-wide parameters
|
|||
.. index:: single: version (in module sys)
|
||||
|
||||
The first word (up to the first space character) is the current Python version;
|
||||
the first three characters are the major and minor version separated by a
|
||||
the first characters are the major and minor version separated by a
|
||||
period. The returned string points into static storage; the caller should not
|
||||
modify its value. The value is available to Python code as :data:`sys.version`.
|
||||
|
||||
See also the :c:var:`Py_Version` constant.
|
||||
|
||||
|
||||
.. c:function:: const char* Py_GetPlatform()
|
||||
|
||||
|
|
@ -614,6 +725,11 @@ Process-wide parameters
|
|||
single: Py_FatalError()
|
||||
single: argv (in module sys)
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.argv`, :c:member:`PyConfig.parse_argv` and
|
||||
:c:member:`PyConfig.safe_path` should be used instead, see :ref:`Python
|
||||
Initialization Configuration <init-config>`.
|
||||
|
||||
Set :data:`sys.argv` based on *argc* and *argv*. These parameters are
|
||||
similar to those passed to the program's :c:func:`main` function with the
|
||||
difference that the first entry should refer to the script file to be
|
||||
|
|
@ -635,7 +751,7 @@ Process-wide parameters
|
|||
directory (``"."``).
|
||||
|
||||
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
|
||||
:c:type:`wchar_*` string.
|
||||
:c:expr:`wchar_*` string.
|
||||
|
||||
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
|
||||
members of the :ref:`Python Initialization Configuration <init-config>`.
|
||||
|
|
@ -657,21 +773,29 @@ Process-wide parameters
|
|||
.. XXX impl. doesn't seem consistent in allowing ``0``/``NULL`` for the params;
|
||||
check w/ Guido.
|
||||
|
||||
.. deprecated:: 3.11
|
||||
|
||||
|
||||
.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv)
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.argv` and :c:member:`PyConfig.parse_argv` should be used
|
||||
instead, see :ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set
|
||||
to ``1`` unless the :program:`python` interpreter was started with the
|
||||
:option:`-I`.
|
||||
|
||||
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
|
||||
:c:type:`wchar_*` string.
|
||||
:c:expr:`wchar_*` string.
|
||||
|
||||
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
|
||||
members of the :ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
.. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`.
|
||||
|
||||
.. deprecated:: 3.11
|
||||
|
||||
|
||||
.. c:function:: void Py_SetPythonHome(const wchar_t *home)
|
||||
|
||||
|
|
@ -689,7 +813,7 @@ Process-wide parameters
|
|||
this storage.
|
||||
|
||||
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
|
||||
:c:type:`wchar_*` string.
|
||||
:c:expr:`wchar_*` string.
|
||||
|
||||
.. deprecated:: 3.11
|
||||
|
||||
|
|
@ -832,11 +956,11 @@ from a C thread is::
|
|||
/* Release the thread. No Python API allowed beyond this point. */
|
||||
PyGILState_Release(gstate);
|
||||
|
||||
Note that the :c:func:`PyGILState_\*` functions assume there is only one global
|
||||
Note that the ``PyGILState_*`` functions assume there is only one global
|
||||
interpreter (created automatically by :c:func:`Py_Initialize`). Python
|
||||
supports the creation of additional interpreters (using
|
||||
:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
|
||||
:c:func:`PyGILState_\*` API is unsupported.
|
||||
``PyGILState_*`` API is unsupported.
|
||||
|
||||
|
||||
.. _fork-and-threads:
|
||||
|
|
@ -899,7 +1023,7 @@ code, or when embedding the Python interpreter:
|
|||
.. c:type:: PyThreadState
|
||||
|
||||
This data structure represents the state of a single thread. The only public
|
||||
data member is :attr:`interp` (:c:type:`PyInterpreterState *`), which points to
|
||||
data member is :attr:`interp` (:c:expr:`PyInterpreterState *`), which points to
|
||||
this thread's interpreter state.
|
||||
|
||||
|
||||
|
|
@ -925,7 +1049,7 @@ code, or when embedding the Python interpreter:
|
|||
.. versionchanged:: 3.2
|
||||
This function cannot be called before :c:func:`Py_Initialize()` anymore.
|
||||
|
||||
.. deprecated-removed:: 3.9 3.11
|
||||
.. deprecated:: 3.9
|
||||
|
||||
.. index:: module: _thread
|
||||
|
||||
|
|
@ -939,7 +1063,7 @@ code, or when embedding the Python interpreter:
|
|||
.. versionchanged:: 3.7
|
||||
The :term:`GIL` is now initialized by :c:func:`Py_Initialize()`.
|
||||
|
||||
.. deprecated-removed:: 3.9 3.11
|
||||
.. deprecated:: 3.9
|
||||
|
||||
|
||||
.. c:function:: PyThreadState* PyEval_SaveThread()
|
||||
|
|
@ -1226,7 +1350,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
|
|||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. c:type:: PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, PyFrameObject *frame, int throwflag)
|
||||
.. c:type:: PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag)
|
||||
|
||||
Type of a frame evaluation function.
|
||||
|
||||
|
|
@ -1236,6 +1360,9 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
|
|||
.. versionchanged:: 3.9
|
||||
The function now takes a *tstate* parameter.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
The *frame* parameter changed from ``PyFrameObject*`` to ``_PyInterpreterFrame*``.
|
||||
|
||||
.. c:function:: _PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
|
||||
|
||||
Get the frame evaluation function.
|
||||
|
|
@ -1273,8 +1400,8 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
|
|||
exception (if any) for the thread is cleared. This raises no exceptions.
|
||||
|
||||
.. versionchanged:: 3.7
|
||||
The type of the *id* parameter changed from :c:type:`long` to
|
||||
:c:type:`unsigned long`.
|
||||
The type of the *id* parameter changed from :c:expr:`long` to
|
||||
:c:expr:`unsigned long`.
|
||||
|
||||
.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate)
|
||||
|
||||
|
|
@ -1460,7 +1587,7 @@ operations executed by such objects may affect the wrong (sub-)interpreter's
|
|||
dictionary of loaded modules. It is equally important to avoid sharing
|
||||
objects from which the above are reachable.
|
||||
|
||||
Also note that combining this functionality with :c:func:`PyGILState_\*` APIs
|
||||
Also note that combining this functionality with ``PyGILState_*`` APIs
|
||||
is delicate, because these APIs assume a bijection between Python thread states
|
||||
and OS-level threads, an assumption broken by the presence of sub-interpreters.
|
||||
It is highly recommended that you don't switch sub-interpreters between a pair
|
||||
|
|
@ -1647,6 +1774,18 @@ Python-level trace functions in previous versions.
|
|||
|
||||
The caller must hold the :term:`GIL`.
|
||||
|
||||
.. c:function:: void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj)
|
||||
|
||||
Like :c:func:`PyEval_SetProfile` but sets the profile function in all running threads
|
||||
belonging to the current interpreter instead of the setting it only on the current thread.
|
||||
|
||||
The caller must hold the :term:`GIL`.
|
||||
|
||||
As :c:func:`PyEval_SetProfile`, this function ignores any exceptions raised while
|
||||
setting the profile functions in all threads.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
.. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)
|
||||
|
||||
|
|
@ -1661,6 +1800,18 @@ Python-level trace functions in previous versions.
|
|||
|
||||
The caller must hold the :term:`GIL`.
|
||||
|
||||
.. c:function:: void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj)
|
||||
|
||||
Like :c:func:`PyEval_SetTrace` but sets the tracing function in all running threads
|
||||
belonging to the current interpreter instead of the setting it only on the current thread.
|
||||
|
||||
The caller must hold the :term:`GIL`.
|
||||
|
||||
As :c:func:`PyEval_SetTrace`, this function ignores any exceptions raised while
|
||||
setting the trace functions in all threads.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
.. _advanced-debugging:
|
||||
|
||||
|
|
@ -1712,7 +1863,7 @@ The Python interpreter provides low-level support for thread-local storage
|
|||
(TLS) which wraps the underlying native TLS implementation to support the
|
||||
Python-level thread local storage API (:class:`threading.local`). The
|
||||
CPython C level APIs are similar to those offered by pthreads and Windows:
|
||||
use a thread key and functions to associate a :c:type:`void*` value per
|
||||
use a thread key and functions to associate a :c:expr:`void*` value per
|
||||
thread.
|
||||
|
||||
The GIL does *not* need to be held when calling these functions; they supply
|
||||
|
|
@ -1723,8 +1874,8 @@ you need to include :file:`pythread.h` to use thread-local storage.
|
|||
|
||||
.. note::
|
||||
None of these API functions handle memory management on behalf of the
|
||||
:c:type:`void*` values. You need to allocate and deallocate them yourself.
|
||||
If the :c:type:`void*` values happen to be :c:type:`PyObject*`, these
|
||||
:c:expr:`void*` values. You need to allocate and deallocate them yourself.
|
||||
If the :c:expr:`void*` values happen to be :c:expr:`PyObject*`, these
|
||||
functions don't do refcount operations on them either.
|
||||
|
||||
.. _thread-specific-storage-api:
|
||||
|
|
@ -1734,7 +1885,7 @@ Thread Specific Storage (TSS) API
|
|||
|
||||
TSS API is introduced to supersede the use of the existing TLS API within the
|
||||
CPython interpreter. This API uses a new type :c:type:`Py_tss_t` instead of
|
||||
:c:type:`int` to represent thread keys.
|
||||
:c:expr:`int` to represent thread keys.
|
||||
|
||||
.. versionadded:: 3.7
|
||||
|
||||
|
|
@ -1778,11 +1929,11 @@ is not possible due to its implementation being opaque at build time.
|
|||
Free the given *key* allocated by :c:func:`PyThread_tss_alloc`, after
|
||||
first calling :c:func:`PyThread_tss_delete` to ensure any associated
|
||||
thread locals have been unassigned. This is a no-op if the *key*
|
||||
argument is `NULL`.
|
||||
argument is ``NULL``.
|
||||
|
||||
.. note::
|
||||
A freed key becomes a dangling pointer, you should reset the key to
|
||||
`NULL`.
|
||||
A freed key becomes a dangling pointer. You should reset the key to
|
||||
``NULL``.
|
||||
|
||||
|
||||
Methods
|
||||
|
|
@ -1820,14 +1971,14 @@ undefined if the given :c:type:`Py_tss_t` has not been initialized by
|
|||
|
||||
.. c:function:: int PyThread_tss_set(Py_tss_t *key, void *value)
|
||||
|
||||
Return a zero value to indicate successfully associating a :c:type:`void*`
|
||||
Return a zero value to indicate successfully associating a :c:expr:`void*`
|
||||
value with a TSS key in the current thread. Each thread has a distinct
|
||||
mapping of the key to a :c:type:`void*` value.
|
||||
mapping of the key to a :c:expr:`void*` value.
|
||||
|
||||
|
||||
.. c:function:: void* PyThread_tss_get(Py_tss_t *key)
|
||||
|
||||
Return the :c:type:`void*` value associated with a TSS key in the current
|
||||
Return the :c:expr:`void*` value associated with a TSS key in the current
|
||||
thread. This returns ``NULL`` if no value is associated with the key in the
|
||||
current thread.
|
||||
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ There are two kinds of configuration:
|
|||
|
||||
* The :ref:`Python Configuration <init-python-config>` can be used to build a
|
||||
customized Python which behaves as the regular Python. For example,
|
||||
environments variables and command line arguments are used to configure
|
||||
environment variables and command line arguments are used to configure
|
||||
Python.
|
||||
|
||||
* The :ref:`Isolated Configuration <init-isolated-conf>` can be used to embed
|
||||
Python into an application. It isolates Python from the system. For example,
|
||||
environments variables are ignored, the LC_CTYPE locale is left unchanged and
|
||||
environment variables are ignored, the LC_CTYPE locale is left unchanged and
|
||||
no signal handler is registered.
|
||||
|
||||
The :c:func:`Py_RunMain` function can be used to write a customized Python
|
||||
|
|
@ -97,7 +97,7 @@ PyWideStringList
|
|||
If *index* is greater than or equal to *list* length, append *item* to
|
||||
*list*.
|
||||
|
||||
*index* must be greater than or equal to 0.
|
||||
*index* must be greater than or equal to ``0``.
|
||||
|
||||
Python must be preinitialized to call this function.
|
||||
|
||||
|
|
@ -254,10 +254,10 @@ PyPreConfig
|
|||
|
||||
.. c:member:: int configure_locale
|
||||
|
||||
Set the LC_CTYPE locale to the user preferred locale?
|
||||
Set the LC_CTYPE locale to the user preferred locale.
|
||||
|
||||
If equals to 0, set :c:member:`~PyPreConfig.coerce_c_locale` and
|
||||
:c:member:`~PyPreConfig.coerce_c_locale_warn` members to 0.
|
||||
If equals to ``0``, set :c:member:`~PyPreConfig.coerce_c_locale` and
|
||||
:c:member:`~PyPreConfig.coerce_c_locale_warn` members to ``0``.
|
||||
|
||||
See the :term:`locale encoding`.
|
||||
|
||||
|
|
@ -265,9 +265,9 @@ PyPreConfig
|
|||
|
||||
.. c:member:: int coerce_c_locale
|
||||
|
||||
If equals to 2, coerce the C locale.
|
||||
If equals to ``2``, coerce the C locale.
|
||||
|
||||
If equals to 1, read the LC_CTYPE locale to decide if it should be
|
||||
If equals to ``1``, read the LC_CTYPE locale to decide if it should be
|
||||
coerced.
|
||||
|
||||
See the :term:`locale encoding`.
|
||||
|
|
@ -282,8 +282,8 @@ PyPreConfig
|
|||
|
||||
.. c:member:: int dev_mode
|
||||
|
||||
If non-zero, enables the :ref:`Python Development Mode <devmode>`:
|
||||
see :c:member:`PyConfig.dev_mode`.
|
||||
:ref:`Python Development Mode <devmode>`: see
|
||||
:c:member:`PyConfig.dev_mode`.
|
||||
|
||||
Default: ``-1`` in Python mode, ``0`` in isolated mode.
|
||||
|
||||
|
|
@ -329,8 +329,10 @@ PyPreConfig
|
|||
|
||||
If non-zero, enable the :ref:`Python UTF-8 Mode <utf8-mode>`.
|
||||
|
||||
Set by the :option:`-X utf8 <-X>` command line option and the
|
||||
:envvar:`PYTHONUTF8` environment variable.
|
||||
Set to ``0`` or ``1`` by the :option:`-X utf8 <-X>` command line option
|
||||
and the :envvar:`PYTHONUTF8` environment variable.
|
||||
|
||||
Also set to ``1`` if the ``LC_CTYPE`` locale is ``C`` or ``POSIX``.
|
||||
|
||||
Default: ``-1`` in Python config and ``0`` in isolated config.
|
||||
|
||||
|
|
@ -479,6 +481,9 @@ PyConfig
|
|||
|
||||
Fields which are already initialized are left unchanged.
|
||||
|
||||
Fields for :ref:`path configuration <init-path-config>` are no longer
|
||||
calculated or modified when calling this function, as of Python 3.11.
|
||||
|
||||
The :c:func:`PyConfig_Read` function only parses
|
||||
:c:member:`PyConfig.argv` arguments once: :c:member:`PyConfig.parse_argv`
|
||||
is set to ``2`` after arguments are parsed. Since Python arguments are
|
||||
|
|
@ -493,6 +498,12 @@ PyConfig
|
|||
parsed, and arguments are only parsed if
|
||||
:c:member:`PyConfig.parse_argv` equals ``1``.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
:c:func:`PyConfig_Read` no longer calculates all paths, and so fields
|
||||
listed under :ref:`Python Path Configuration <init-path-config>` may
|
||||
no longer be updated until :c:func:`Py_InitializeFromConfig` is
|
||||
called.
|
||||
|
||||
.. c:function:: void PyConfig_Clear(PyConfig *config)
|
||||
|
||||
Release configuration memory.
|
||||
|
|
@ -534,6 +545,25 @@ PyConfig
|
|||
|
||||
See also the :c:member:`~PyConfig.orig_argv` member.
|
||||
|
||||
.. c:member:: int safe_path
|
||||
|
||||
If equals to zero, ``Py_RunMain()`` prepends a potentially unsafe path to
|
||||
:data:`sys.path` at startup:
|
||||
|
||||
* If :c:member:`argv[0] <PyConfig.argv>` is equal to ``L"-m"``
|
||||
(``python -m module``), prepend the current working directory.
|
||||
* If running a script (``python script.py``), prepend the script's
|
||||
directory. If it's a symbolic link, resolve symbolic links.
|
||||
* Otherwise (``python -c code`` and ``python``), prepend an empty string,
|
||||
which means the current working directory.
|
||||
|
||||
Set to ``1`` by the :option:`-P` command line option and the
|
||||
:envvar:`PYTHONSAFEPATH` environment variable.
|
||||
|
||||
Default: ``0`` in Python config, ``1`` in isolated config.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:member:: wchar_t* base_exec_prefix
|
||||
|
||||
:data:`sys.base_exec_prefix`.
|
||||
|
|
@ -564,10 +594,10 @@ PyConfig
|
|||
|
||||
.. c:member:: int buffered_stdio
|
||||
|
||||
If equals to 0 and :c:member:`~PyConfig.configure_c_stdio` is non-zero,
|
||||
If equals to ``0`` and :c:member:`~PyConfig.configure_c_stdio` is non-zero,
|
||||
disable buffering on the C streams stdout and stderr.
|
||||
|
||||
Set to 0 by the :option:`-u` command line option and the
|
||||
Set to ``0`` by the :option:`-u` command line option and the
|
||||
:envvar:`PYTHONUNBUFFERED` environment variable.
|
||||
|
||||
stdin is always opened in buffered mode.
|
||||
|
|
@ -576,11 +606,11 @@ PyConfig
|
|||
|
||||
.. c:member:: int bytes_warning
|
||||
|
||||
If equals to 1, issue a warning when comparing :class:`bytes` or
|
||||
If equals to ``1``, issue a warning when comparing :class:`bytes` or
|
||||
:class:`bytearray` with :class:`str`, or comparing :class:`bytes` with
|
||||
:class:`int`.
|
||||
|
||||
If equal or greater to 2, raise a :exc:`BytesWarning` exception in these
|
||||
If equal or greater to ``2``, raise a :exc:`BytesWarning` exception in these
|
||||
cases.
|
||||
|
||||
Incremented by the :option:`-b` command line option.
|
||||
|
|
@ -596,13 +626,16 @@ PyConfig
|
|||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. c:member:: int no_debug_ranges
|
||||
.. c:member:: int code_debug_ranges
|
||||
|
||||
If equals to ``1``, disables the inclusion of the end line and column
|
||||
If equals to ``0``, disables the inclusion of the end line and column
|
||||
mappings in code objects. Also disables traceback printing carets to
|
||||
specific error locations.
|
||||
|
||||
Default: ``0``.
|
||||
Set to ``0`` by the :envvar:`PYTHONNODEBUGRANGES` environment variable
|
||||
and by the :option:`-X no_debug_ranges <-X>` command line option.
|
||||
|
||||
Default: ``1``.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
|
@ -640,11 +673,14 @@ PyConfig
|
|||
|
||||
If non-zero, enable the :ref:`Python Development Mode <devmode>`.
|
||||
|
||||
Set to ``1`` by the :option:`-X dev <-X>` option and the
|
||||
:envvar:`PYTHONDEVMODE` environment variable.
|
||||
|
||||
Default: ``-1`` in Python mode, ``0`` in isolated mode.
|
||||
|
||||
.. c:member:: int dump_refs
|
||||
|
||||
Dump Python refererences?
|
||||
Dump Python references?
|
||||
|
||||
If non-zero, dump all objects which are still alive at exit.
|
||||
|
||||
|
|
@ -699,9 +735,8 @@ PyConfig
|
|||
|
||||
* ``"utf-8"`` if :c:member:`PyPreConfig.utf8_mode` is non-zero.
|
||||
* ``"ascii"`` if Python detects that ``nl_langinfo(CODESET)`` announces
|
||||
the ASCII encoding (or Roman8 encoding on HP-UX), whereas the
|
||||
``mbstowcs()`` function decodes from a different encoding (usually
|
||||
Latin1).
|
||||
the ASCII encoding, whereas the ``mbstowcs()`` function
|
||||
decodes from a different encoding (usually Latin1).
|
||||
* ``"utf-8"`` if ``nl_langinfo(CODESET)`` returns an empty string.
|
||||
* Otherwise, use the :term:`locale encoding`:
|
||||
``nl_langinfo(CODESET)`` result.
|
||||
|
|
@ -769,7 +804,7 @@ PyConfig
|
|||
|
||||
Enter interactive mode after executing a script or a command.
|
||||
|
||||
If greater than 0, enable inspect: when a script is passed as first
|
||||
If greater than ``0``, enable inspect: when a script is passed as first
|
||||
argument or the -c option is used, enter interactive mode after executing
|
||||
the script or the command, even when :data:`sys.stdin` does not appear to
|
||||
be a terminal.
|
||||
|
|
@ -787,27 +822,51 @@ PyConfig
|
|||
|
||||
.. c:member:: int interactive
|
||||
|
||||
If greater than 0, enable the interactive mode (REPL).
|
||||
If greater than ``0``, enable the interactive mode (REPL).
|
||||
|
||||
Incremented by the :option:`-i` command line option.
|
||||
|
||||
Default: ``0``.
|
||||
|
||||
.. c:member:: int int_max_str_digits
|
||||
|
||||
Configures the :ref:`integer string conversion length limitation
|
||||
<int_max_str_digits>`. An initial value of ``-1`` means the value will
|
||||
be taken from the command line or environment or otherwise default to
|
||||
4300 (:data:`sys.int_info.default_max_str_digits`). A value of ``0``
|
||||
disables the limitation. Values greater than zero but less than 640
|
||||
(:data:`sys.int_info.str_digits_check_threshold`) are unsupported and
|
||||
will produce an error.
|
||||
|
||||
Configured by the :option:`-X int_max_str_digits <-X>` command line
|
||||
flag or the :envvar:`PYTHONINTMAXSTRDIGITS` environment variable.
|
||||
|
||||
Default: ``-1`` in Python mode. 4300
|
||||
(:data:`sys.int_info.default_max_str_digits`) in isolated mode.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:member:: int isolated
|
||||
|
||||
If greater than 0, enable isolated mode:
|
||||
If greater than ``0``, enable isolated mode:
|
||||
|
||||
* :data:`sys.path` contains neither the script's directory (computed from
|
||||
``argv[0]`` or the current directory) nor the user's site-packages
|
||||
directory.
|
||||
* Set :c:member:`~PyConfig.safe_path` to ``1``:
|
||||
don't prepend a potentially unsafe path to :data:`sys.path` at Python
|
||||
startup, such as the current directory, the script's directory or an
|
||||
empty string.
|
||||
* Set :c:member:`~PyConfig.use_environment` to ``0``: ignore ``PYTHON``
|
||||
environment variables.
|
||||
* Set :c:member:`~PyConfig.user_site_directory` to ``0``: don't add the user
|
||||
site directory to :data:`sys.path`.
|
||||
* Python REPL doesn't import :mod:`readline` nor enable default readline
|
||||
configuration on interactive prompts.
|
||||
* Set :c:member:`~PyConfig.use_environment` and
|
||||
:c:member:`~PyConfig.user_site_directory` to 0.
|
||||
|
||||
Set to ``1`` by the :option:`-I` command line option.
|
||||
|
||||
Default: ``0`` in Python mode, ``1`` in isolated mode.
|
||||
|
||||
See also :c:member:`PyPreConfig.isolated`.
|
||||
See also the :ref:`Isolated Configuration <init-isolated-conf>` and
|
||||
:c:member:`PyPreConfig.isolated`.
|
||||
|
||||
.. c:member:: int legacy_windows_stdio
|
||||
|
||||
|
|
@ -845,12 +904,19 @@ PyConfig
|
|||
|
||||
Default: value of the ``PLATLIBDIR`` macro which is set by the
|
||||
:option:`configure --with-platlibdir option <--with-platlibdir>`
|
||||
(default: ``"lib"``).
|
||||
(default: ``"lib"``, or ``"DLLs"`` on Windows).
|
||||
|
||||
Part of the :ref:`Python Path Configuration <init-path-config>` input.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
This macro is now used on Windows to locate the standard
|
||||
library extension modules, typically under ``DLLs``. However,
|
||||
for compatibility, note that this value is ignored for any
|
||||
non-standard layouts, including in-tree builds and virtual
|
||||
environments.
|
||||
|
||||
.. c:member:: wchar_t* pythonpath_env
|
||||
|
||||
Module search paths (:data:`sys.path`) as a string separated by ``DELIM``
|
||||
|
|
@ -867,9 +933,9 @@ PyConfig
|
|||
|
||||
Module search paths: :data:`sys.path`.
|
||||
|
||||
If :c:member:`~PyConfig.module_search_paths_set` is equal to 0, the
|
||||
function calculating the :ref:`Python Path Configuration <init-path-config>`
|
||||
overrides the :c:member:`~PyConfig.module_search_paths` and sets
|
||||
If :c:member:`~PyConfig.module_search_paths_set` is equal to ``0``,
|
||||
:c:func:`Py_InitializeFromConfig` will replace
|
||||
:c:member:`~PyConfig.module_search_paths` and sets
|
||||
:c:member:`~PyConfig.module_search_paths_set` to ``1``.
|
||||
|
||||
Default: empty list (``module_search_paths``) and ``0``
|
||||
|
|
@ -931,26 +997,29 @@ PyConfig
|
|||
|
||||
.. c:member:: int parser_debug
|
||||
|
||||
Parser debug mode. If greater than 0, turn on parser debugging output (for expert only, depending
|
||||
Parser debug mode. If greater than ``0``, turn on parser debugging output (for expert only, depending
|
||||
on compilation options).
|
||||
|
||||
Incremented by the :option:`-d` command line option. Set to the
|
||||
:envvar:`PYTHONDEBUG` environment variable value.
|
||||
|
||||
Need a :ref:`debug build of Python <debug-build>` (the ``Py_DEBUG`` macro
|
||||
must be defined).
|
||||
|
||||
Default: ``0``.
|
||||
|
||||
.. c:member:: int pathconfig_warnings
|
||||
|
||||
On Unix, if non-zero, calculating the :ref:`Python Path Configuration
|
||||
<init-path-config>` can log warnings into ``stderr``. If equals to 0,
|
||||
suppress these warnings.
|
||||
|
||||
It has no effect on Windows.
|
||||
If non-zero, calculation of path configuration is allowed to log
|
||||
warnings into ``stderr``. If equals to ``0``, suppress these warnings.
|
||||
|
||||
Default: ``1`` in Python mode, ``0`` in isolated mode.
|
||||
|
||||
Part of the :ref:`Python Path Configuration <init-path-config>` input.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Now also applies on Windows.
|
||||
|
||||
.. c:member:: wchar_t* prefix
|
||||
|
||||
The site-specific directory prefix where the platform independent Python
|
||||
|
|
@ -992,7 +1061,7 @@ PyConfig
|
|||
|
||||
.. c:member:: int quiet
|
||||
|
||||
Quiet mode. If greater than 0, don't display the copyright and version at
|
||||
Quiet mode. If greater than ``0``, don't display the copyright and version at
|
||||
Python startup in interactive mode.
|
||||
|
||||
Incremented by the :option:`-q` command line option.
|
||||
|
|
@ -1010,12 +1079,13 @@ PyConfig
|
|||
.. c:member:: wchar_t* run_filename
|
||||
|
||||
Filename passed on the command line: trailing command line argument
|
||||
without :option:`-c` or :option:`-m`.
|
||||
without :option:`-c` or :option:`-m`. It is used by the
|
||||
:c:func:`Py_RunMain` function.
|
||||
|
||||
For example, it is set to ``script.py`` by the ``python3 script.py arg``
|
||||
command.
|
||||
command line.
|
||||
|
||||
Used by :c:func:`Py_RunMain`.
|
||||
See also the :c:member:`PyConfig.skip_source_first_line` option.
|
||||
|
||||
Default: ``NULL``.
|
||||
|
||||
|
|
@ -1031,7 +1101,7 @@ PyConfig
|
|||
|
||||
Show total reference count at exit?
|
||||
|
||||
Set to 1 by :option:`-X showrefcount <-X>` command line option.
|
||||
Set to ``1`` by :option:`-X showrefcount <-X>` command line option.
|
||||
|
||||
Need a :ref:`debug build of Python <debug-build>` (the ``Py_REF_DEBUG``
|
||||
macro must be defined).
|
||||
|
|
@ -1103,6 +1173,20 @@ PyConfig
|
|||
|
||||
Default: ``-1`` in Python mode, ``0`` in isolated mode.
|
||||
|
||||
.. c:member:: int perf_profiling
|
||||
|
||||
Enable compatibility mode with the perf profiler?
|
||||
|
||||
If non-zero, initialize the perf trampoline. See :ref:`perf_profiling`
|
||||
for more information.
|
||||
|
||||
Set by :option:`-X perf <-X>` command line option and by the
|
||||
:envvar:`PYTHONPERFSUPPORT` environment variable.
|
||||
|
||||
Default: ``-1``.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. c:member:: int use_environment
|
||||
|
||||
Use :ref:`environment variables <using-on-envvars>`?
|
||||
|
|
@ -1110,6 +1194,8 @@ PyConfig
|
|||
If equals to zero, ignore the :ref:`environment variables
|
||||
<using-on-envvars>`.
|
||||
|
||||
Set to ``0`` by the :option:`-E` environment variable.
|
||||
|
||||
Default: ``1`` in Python config and ``0`` in isolated config.
|
||||
|
||||
.. c:member:: int user_site_directory
|
||||
|
|
@ -1124,17 +1210,17 @@ PyConfig
|
|||
|
||||
.. c:member:: int verbose
|
||||
|
||||
Verbose mode. If greater than 0, print a message each time a module is
|
||||
Verbose mode. If greater than ``0``, print a message each time a module is
|
||||
imported, showing the place (filename or built-in module) from which
|
||||
it is loaded.
|
||||
|
||||
If greater or equal to 2, print a message for each file that is checked
|
||||
for when searching for a module. Also provides information on module
|
||||
cleanup at exit.
|
||||
If greater than or equal to ``2``, print a message for each file that is
|
||||
checked for when searching for a module. Also provides information on
|
||||
module cleanup at exit.
|
||||
|
||||
Incremented by the :option:`-v` command line option.
|
||||
|
||||
Set to the :envvar:`PYTHONVERBOSE` environment variable value.
|
||||
Set by the :envvar:`PYTHONVERBOSE` environment variable value.
|
||||
|
||||
Default: ``0``.
|
||||
|
||||
|
|
@ -1159,7 +1245,7 @@ PyConfig
|
|||
|
||||
.. c:member:: int write_bytecode
|
||||
|
||||
If equal to 0, Python won't try to write ``.pyc`` files on the import of
|
||||
If equal to ``0``, Python won't try to write ``.pyc`` files on the import of
|
||||
source modules.
|
||||
|
||||
Set to ``0`` by the :option:`-B` command line option and the
|
||||
|
|
@ -1240,7 +1326,11 @@ Example setting the program name::
|
|||
}
|
||||
|
||||
More complete example modifying the default configuration, read the
|
||||
configuration, and then override some parameters::
|
||||
configuration, and then override some parameters. Note that since
|
||||
3.11, many parameters are not calculated until initialization, and
|
||||
so values cannot be read from the configuration structure. Any values
|
||||
set before initialize is called will be left unchanged by
|
||||
initialization::
|
||||
|
||||
PyStatus init_python(const char *program_name)
|
||||
{
|
||||
|
|
@ -1265,7 +1355,15 @@ configuration, and then override some parameters::
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Append our custom search path to sys.path */
|
||||
/* Specify sys.path explicitly */
|
||||
/* If you want to modify the default set of paths, finish
|
||||
initialization first and then use PySys_GetObject("path") */
|
||||
config.module_search_paths_set = 1;
|
||||
status = PyWideStringList_Append(&config.module_search_paths,
|
||||
L"/path/to/stdlib");
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto done;
|
||||
}
|
||||
status = PyWideStringList_Append(&config.module_search_paths,
|
||||
L"/path/to/more/modules");
|
||||
if (PyStatus_Exception(status)) {
|
||||
|
|
@ -1297,15 +1395,14 @@ Isolated Configuration
|
|||
isolate Python from the system. For example, to embed Python into an
|
||||
application.
|
||||
|
||||
This configuration ignores global configuration variables, environments
|
||||
This configuration ignores global configuration variables, environment
|
||||
variables, command line arguments (:c:member:`PyConfig.argv` is not parsed)
|
||||
and user site directory. The C standard streams (ex: ``stdout``) and the
|
||||
LC_CTYPE locale are left unchanged. Signal handlers are not installed.
|
||||
|
||||
Configuration files are still used with this configuration. Set the
|
||||
:ref:`Python Path Configuration <init-path-config>` ("output fields") to ignore these
|
||||
configuration files and avoid the function computing the default path
|
||||
configuration.
|
||||
Configuration files are still used with this configuration to determine
|
||||
paths that are unspecified. Ensure :c:member:`PyConfig.home` is specified
|
||||
to avoid computing the default path configuration.
|
||||
|
||||
|
||||
.. _init-python-config:
|
||||
|
|
@ -1361,18 +1458,18 @@ Python Path Configuration
|
|||
|
||||
If at least one "output field" is not set, Python calculates the path
|
||||
configuration to fill unset fields. If
|
||||
:c:member:`~PyConfig.module_search_paths_set` is equal to 0,
|
||||
:c:member:`~PyConfig.module_search_paths_set` is equal to ``0``,
|
||||
:c:member:`~PyConfig.module_search_paths` is overridden and
|
||||
:c:member:`~PyConfig.module_search_paths_set` is set to 1.
|
||||
:c:member:`~PyConfig.module_search_paths_set` is set to ``1``.
|
||||
|
||||
It is possible to completely ignore the function calculating the default
|
||||
path configuration by setting explicitly all path configuration output
|
||||
fields listed above. A string is considered as set even if it is non-empty.
|
||||
``module_search_paths`` is considered as set if
|
||||
``module_search_paths_set`` is set to 1. In this case, path
|
||||
configuration input fields are ignored as well.
|
||||
``module_search_paths_set`` is set to ``1``. In this case,
|
||||
``module_search_paths`` will be used without modification.
|
||||
|
||||
Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when
|
||||
Set :c:member:`~PyConfig.pathconfig_warnings` to ``0`` to suppress warnings when
|
||||
calculating the path configuration (Unix only, Windows does not log any warning).
|
||||
|
||||
If :c:member:`~PyConfig.base_prefix` or :c:member:`~PyConfig.base_exec_prefix`
|
||||
|
|
@ -1401,9 +1498,16 @@ site-package directory to :data:`sys.path`.
|
|||
The following configuration files are used by the path configuration:
|
||||
|
||||
* ``pyvenv.cfg``
|
||||
* ``python._pth`` (Windows only)
|
||||
* ``._pth`` file (ex: ``python._pth``)
|
||||
* ``pybuilddir.txt`` (Unix only)
|
||||
|
||||
If a ``._pth`` file is present:
|
||||
|
||||
* Set :c:member:`~PyConfig.isolated` to ``1``.
|
||||
* Set :c:member:`~PyConfig.use_environment` to ``0``.
|
||||
* Set :c:member:`~PyConfig.site_import` to ``0``.
|
||||
* Set :c:member:`~PyConfig.safe_path` to ``1``.
|
||||
|
||||
The ``__PYVENV_LAUNCHER__`` environment variable is used to set
|
||||
:c:member:`PyConfig.base_executable`
|
||||
|
||||
|
|
@ -1442,7 +1546,7 @@ Multi-Phase Initialization Private Provisional API
|
|||
==================================================
|
||||
|
||||
This section is a private provisional API introducing multi-phase
|
||||
initialization, the core feature of the :pep:`432`:
|
||||
initialization, the core feature of :pep:`432`:
|
||||
|
||||
* "Core" initialization phase, "bare minimum Python":
|
||||
|
||||
|
|
@ -1465,10 +1569,8 @@ initialization, the core feature of the :pep:`432`:
|
|||
|
||||
Private provisional API:
|
||||
|
||||
* :c:member:`PyConfig._init_main`: if set to 0,
|
||||
* :c:member:`PyConfig._init_main`: if set to ``0``,
|
||||
:c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase.
|
||||
* :c:member:`PyConfig._isolated_interpreter`: if non-zero,
|
||||
disallow threads, subprocesses and fork.
|
||||
|
||||
.. c:function:: PyStatus _Py_InitializeMain(void)
|
||||
|
||||
|
|
@ -1480,7 +1582,7 @@ applied during the "Main" phase. It may allow to customize Python in Python to
|
|||
override or tune the :ref:`Path Configuration <init-path-config>`, maybe
|
||||
install a custom :data:`sys.meta_path` importer or an import hook, etc.
|
||||
|
||||
It may become possible to calculatin the :ref:`Path Configuration
|
||||
It may become possible to calculate the :ref:`Path Configuration
|
||||
<init-path-config>` in Python, after the Core phase and before the Main phase,
|
||||
which is one of the :pep:`432` motivation.
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ complete listing.
|
|||
.. c:macro:: Py_GETENV(s)
|
||||
|
||||
Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
|
||||
command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set).
|
||||
command line (see :c:member:`PyConfig.use_environment`).
|
||||
|
||||
.. c:macro:: Py_MAX(x, y)
|
||||
|
||||
|
|
@ -264,13 +264,13 @@ Objects, Types and Reference Counts
|
|||
.. index:: object: type
|
||||
|
||||
Most Python/C API functions have one or more arguments as well as a return value
|
||||
of type :c:type:`PyObject*`. This type is a pointer to an opaque data type
|
||||
of type :c:expr:`PyObject*`. This type is a pointer to an opaque data type
|
||||
representing an arbitrary Python object. Since all Python object types are
|
||||
treated the same way by the Python language in most situations (e.g.,
|
||||
assignments, scope rules, and argument passing), it is only fitting that they
|
||||
should be represented by a single C type. Almost all Python objects live on the
|
||||
heap: you never declare an automatic or static variable of type
|
||||
:c:type:`PyObject`, only pointer variables of type :c:type:`PyObject*` can be
|
||||
:c:type:`PyObject`, only pointer variables of type :c:expr:`PyObject*` can be
|
||||
declared. The sole exception are the type objects; since these must never be
|
||||
deallocated, they are typically static :c:type:`PyTypeObject` objects.
|
||||
|
||||
|
|
@ -530,13 +530,20 @@ Types
|
|||
-----
|
||||
|
||||
There are few other data types that play a significant role in the Python/C
|
||||
API; most are simple C types such as :c:type:`int`, :c:type:`long`,
|
||||
:c:type:`double` and :c:type:`char*`. A few structure types are used to
|
||||
API; most are simple C types such as :c:expr:`int`, :c:expr:`long`,
|
||||
:c:expr:`double` and :c:expr:`char*`. A few structure types are used to
|
||||
describe static tables used to list the functions exported by a module or the
|
||||
data attributes of a new object type, and another is used to describe the value
|
||||
of a complex number. These will be discussed together with the functions that
|
||||
use them.
|
||||
|
||||
.. c:type:: Py_ssize_t
|
||||
|
||||
A signed integral type such that ``sizeof(Py_ssize_t) == sizeof(size_t)``.
|
||||
C99 doesn't define such a thing directly (size_t is an unsigned integral type).
|
||||
See :pep:`353` for details. ``PY_SSIZE_T_MAX`` is the largest positive value
|
||||
of type :c:type:`Py_ssize_t`.
|
||||
|
||||
|
||||
.. _api-exceptions:
|
||||
|
||||
|
|
@ -709,12 +716,10 @@ the table of loaded modules, and creates the fundamental modules
|
|||
:mod:`builtins`, :mod:`__main__`, and :mod:`sys`. It also
|
||||
initializes the module search path (``sys.path``).
|
||||
|
||||
.. index:: single: PySys_SetArgvEx()
|
||||
|
||||
:c:func:`Py_Initialize` does not set the "script argument list" (``sys.argv``).
|
||||
If this variable is needed by Python code that will be executed later, it must
|
||||
be set explicitly with a call to ``PySys_SetArgvEx(argc, argv, updatepath)``
|
||||
after the call to :c:func:`Py_Initialize`.
|
||||
If this variable is needed by Python code that will be executed later, setting
|
||||
:c:member:`PyConfig.argv` and :c:member:`PyConfig.parse_argv` must be set: see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
On most systems (in particular, on Unix and Windows, although the details are
|
||||
slightly different), :c:func:`Py_Initialize` calculates the module search path
|
||||
|
|
@ -774,7 +779,7 @@ A full list of the various types of debugging builds is in the file
|
|||
:file:`Misc/SpecialBuilds.txt` in the Python source distribution. Builds are
|
||||
available that support tracing of reference counts, debugging the memory
|
||||
allocator, or low-level profiling of the main interpreter loop. Only the most
|
||||
frequently-used builds will be described in the remainder of this section.
|
||||
frequently used builds will be described in the remainder of this section.
|
||||
|
||||
Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces
|
||||
what is generally meant by :ref:`a debug build of Python <debug-build>`.
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ There are two functions specifically for working with iterators.
|
|||
|
||||
.. c:function:: int PyAIter_Check(PyObject *o)
|
||||
|
||||
Returns non-zero if the object 'obj' provides :class:`AsyncIterator`
|
||||
protocols, and ``0`` otherwise. This function always succeeds.
|
||||
Return non-zero if the object *o* provides the :class:`AsyncIterator`
|
||||
protocol, and ``0`` otherwise. This function always succeeds.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ List Objects
|
|||
|
||||
.. c:function:: Py_ssize_t PyList_GET_SIZE(PyObject *list)
|
||||
|
||||
Macro form of :c:func:`PyList_Size` without error checking.
|
||||
Similar to :c:func:`PyList_Size`, but without error checking.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)
|
||||
|
|
@ -66,7 +66,7 @@ List Objects
|
|||
|
||||
.. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)
|
||||
|
||||
Macro form of :c:func:`PyList_GetItem` without error checking.
|
||||
Similar to :c:func:`PyList_GetItem`, but without error checking.
|
||||
|
||||
|
||||
.. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
Return a new :c:type:`PyLongObject` object from *v*, or ``NULL`` on failure.
|
||||
|
||||
The current implementation keeps an array of integer objects for all integers
|
||||
between ``-5`` and ``256``, when you create an int in that range you actually
|
||||
between ``-5`` and ``256``. When you create an int in that range you actually
|
||||
just get back a reference to the existing object.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyLong_FromUnsignedLong(unsigned long v)
|
||||
|
||||
Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long`, or
|
||||
Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long`, or
|
||||
``NULL`` on failure.
|
||||
|
||||
|
||||
|
|
@ -65,13 +65,13 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
|
||||
.. c:function:: PyObject* PyLong_FromLongLong(long long v)
|
||||
|
||||
Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or ``NULL``
|
||||
Return a new :c:type:`PyLongObject` object from a C :c:expr:`long long`, or ``NULL``
|
||||
on failure.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v)
|
||||
|
||||
Return a new :c:type:`PyLongObject` object from a C :c:type:`unsigned long long`,
|
||||
Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long long`,
|
||||
or ``NULL`` on failure.
|
||||
|
||||
|
||||
|
|
@ -84,14 +84,19 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
.. c:function:: PyObject* PyLong_FromString(const char *str, char **pend, int base)
|
||||
|
||||
Return a new :c:type:`PyLongObject` based on the string value in *str*, which
|
||||
is interpreted according to the radix in *base*. If *pend* is non-``NULL``,
|
||||
*\*pend* will point to the first character in *str* which follows the
|
||||
representation of the number. If *base* is ``0``, *str* is interpreted using
|
||||
the :ref:`integers` definition; in this case, leading zeros in a
|
||||
non-zero decimal number raises a :exc:`ValueError`. If *base* is not ``0``,
|
||||
it must be between ``2`` and ``36``, inclusive. Leading spaces and single
|
||||
underscores after a base specifier and between digits are ignored. If there
|
||||
are no digits, :exc:`ValueError` will be raised.
|
||||
is interpreted according to the radix in *base*, or ``NULL`` on failure. If
|
||||
*pend* is non-``NULL``, *\*pend* will point to the end of *str* on success or
|
||||
to the first character that could not be processed on error. If *base* is ``0``,
|
||||
*str* is interpreted using the :ref:`integers` definition; in this case, leading
|
||||
zeros in a non-zero decimal number raises a :exc:`ValueError`. If *base* is not
|
||||
``0``, it must be between ``2`` and ``36``, inclusive. Leading and trailing
|
||||
whitespace and single underscores after a base specifier and between digits are
|
||||
ignored. If there are no digits or *str* is not NULL-terminated following the
|
||||
digits and trailing whitespace, :exc:`ValueError` will be raised.
|
||||
|
||||
.. seealso:: Python methods :meth:`int.to_bytes` and :meth:`int.from_bytes`
|
||||
to convert a :c:type:`PyLongObject` to/from an array of bytes in base
|
||||
``256``. You can call those from C using :c:func:`PyObject_CallMethod`.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyLong_FromUnicodeObject(PyObject *u, int base)
|
||||
|
|
@ -115,12 +120,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
single: LONG_MAX
|
||||
single: OverflowError (built-in exception)
|
||||
|
||||
Return a C :c:type:`long` representation of *obj*. If *obj* is not an
|
||||
Return a C :c:expr:`long` representation of *obj*. If *obj* is not an
|
||||
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
|
||||
(if present) to convert it to a :c:type:`PyLongObject`.
|
||||
|
||||
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
|
||||
:c:type:`long`.
|
||||
:c:expr:`long`.
|
||||
|
||||
Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||
|
||||
|
|
@ -133,7 +138,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
|
||||
.. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow)
|
||||
|
||||
Return a C :c:type:`long` representation of *obj*. If *obj* is not an
|
||||
Return a C :c:expr:`long` representation of *obj*. If *obj* is not an
|
||||
instance of :c:type:`PyLongObject`, first call its :meth:`__index__`
|
||||
method (if present) to convert it to a :c:type:`PyLongObject`.
|
||||
|
||||
|
|
@ -156,12 +161,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
.. index::
|
||||
single: OverflowError (built-in exception)
|
||||
|
||||
Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
|
||||
Return a C :c:expr:`long long` representation of *obj*. If *obj* is not an
|
||||
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
|
||||
(if present) to convert it to a :c:type:`PyLongObject`.
|
||||
|
||||
Raise :exc:`OverflowError` if the value of *obj* is out of range for a
|
||||
:c:type:`long long`.
|
||||
:c:expr:`long long`.
|
||||
|
||||
Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||
|
||||
|
|
@ -174,7 +179,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
|
||||
.. c:function:: long long PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow)
|
||||
|
||||
Return a C :c:type:`long long` representation of *obj*. If *obj* is not an
|
||||
Return a C :c:expr:`long long` representation of *obj*. If *obj* is not an
|
||||
instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method
|
||||
(if present) to convert it to a :c:type:`PyLongObject`.
|
||||
|
||||
|
|
@ -215,11 +220,11 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
single: ULONG_MAX
|
||||
single: OverflowError (built-in exception)
|
||||
|
||||
Return a C :c:type:`unsigned long` representation of *pylong*. *pylong*
|
||||
Return a C :c:expr:`unsigned long` representation of *pylong*. *pylong*
|
||||
must be an instance of :c:type:`PyLongObject`.
|
||||
|
||||
Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
|
||||
:c:type:`unsigned long`.
|
||||
:c:expr:`unsigned long`.
|
||||
|
||||
Returns ``(unsigned long)-1`` on error.
|
||||
Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||
|
|
@ -246,11 +251,11 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
.. index::
|
||||
single: OverflowError (built-in exception)
|
||||
|
||||
Return a C :c:type:`unsigned long long` representation of *pylong*. *pylong*
|
||||
Return a C :c:expr:`unsigned long long` representation of *pylong*. *pylong*
|
||||
must be an instance of :c:type:`PyLongObject`.
|
||||
|
||||
Raise :exc:`OverflowError` if the value of *pylong* is out of range for an
|
||||
:c:type:`unsigned long long`.
|
||||
:c:expr:`unsigned long long`.
|
||||
|
||||
Returns ``(unsigned long long)-1`` on error.
|
||||
Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||
|
|
@ -261,11 +266,11 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
|
||||
.. c:function:: unsigned long PyLong_AsUnsignedLongMask(PyObject *obj)
|
||||
|
||||
Return a C :c:type:`unsigned long` representation of *obj*. If *obj* is not
|
||||
Return a C :c:expr:`unsigned long` representation of *obj*. If *obj* is not
|
||||
an instance of :c:type:`PyLongObject`, first call its :meth:`__index__`
|
||||
method (if present) to convert it to a :c:type:`PyLongObject`.
|
||||
|
||||
If the value of *obj* is out of range for an :c:type:`unsigned long`,
|
||||
If the value of *obj* is out of range for an :c:expr:`unsigned long`,
|
||||
return the reduction of that value modulo ``ULONG_MAX + 1``.
|
||||
|
||||
Returns ``(unsigned long)-1`` on error. Use :c:func:`PyErr_Occurred` to
|
||||
|
|
@ -280,12 +285,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
|
||||
.. c:function:: unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj)
|
||||
|
||||
Return a C :c:type:`unsigned long long` representation of *obj*. If *obj*
|
||||
Return a C :c:expr:`unsigned long long` representation of *obj*. If *obj*
|
||||
is not an instance of :c:type:`PyLongObject`, first call its
|
||||
:meth:`__index__` method (if present) to convert it to a
|
||||
:c:type:`PyLongObject`.
|
||||
|
||||
If the value of *obj* is out of range for an :c:type:`unsigned long long`,
|
||||
If the value of *obj* is out of range for an :c:expr:`unsigned long long`,
|
||||
return the reduction of that value modulo ``ULLONG_MAX + 1``.
|
||||
|
||||
Returns ``(unsigned long long)-1`` on error. Use :c:func:`PyErr_Occurred`
|
||||
|
|
@ -300,20 +305,20 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
|
||||
.. c:function:: double PyLong_AsDouble(PyObject *pylong)
|
||||
|
||||
Return a C :c:type:`double` representation of *pylong*. *pylong* must be
|
||||
Return a C :c:expr:`double` representation of *pylong*. *pylong* must be
|
||||
an instance of :c:type:`PyLongObject`.
|
||||
|
||||
Raise :exc:`OverflowError` if the value of *pylong* is out of range for a
|
||||
:c:type:`double`.
|
||||
:c:expr:`double`.
|
||||
|
||||
Returns ``-1.0`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||
|
||||
|
||||
.. c:function:: void* PyLong_AsVoidPtr(PyObject *pylong)
|
||||
|
||||
Convert a Python integer *pylong* to a C :c:type:`void` pointer.
|
||||
Convert a Python integer *pylong* to a C :c:expr:`void` pointer.
|
||||
If *pylong* cannot be converted, an :exc:`OverflowError` will be raised. This
|
||||
is only assured to produce a usable :c:type:`void` pointer for values created
|
||||
is only assured to produce a usable :c:expr:`void` pointer for values created
|
||||
with :c:func:`PyLong_FromVoidPtr`.
|
||||
|
||||
Returns ``NULL`` on error. Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
|
|||
|
||||
.. c:function:: int PyMapping_Check(PyObject *o)
|
||||
|
||||
Return ``1`` if the object provides mapping protocol or supports slicing,
|
||||
Return ``1`` if the object provides the mapping protocol or supports slicing,
|
||||
and ``0`` otherwise. Note that it returns ``1`` for Python classes with
|
||||
a :meth:`__getitem__` method since in general case it is impossible to
|
||||
determine what type of keys it supports. This function always succeeds.
|
||||
a :meth:`__getitem__` method, since in general it is impossible to
|
||||
determine what type of keys the class supports. This function always succeeds.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ unmarshalling. Version 2 uses a binary format for floating point numbers.
|
|||
|
||||
.. c:function:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
|
||||
|
||||
Marshal a :c:type:`long` integer, *value*, to *file*. This will only write
|
||||
Marshal a :c:expr:`long` integer, *value*, to *file*. This will only write
|
||||
the least-significant 32 bits of *value*; regardless of the size of the
|
||||
native :c:type:`long` type. *version* indicates the file format.
|
||||
native :c:expr:`long` type. *version* indicates the file format.
|
||||
|
||||
|
||||
.. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)
|
||||
|
|
@ -43,9 +43,9 @@ The following functions allow marshalled values to be read back in.
|
|||
|
||||
.. c:function:: long PyMarshal_ReadLongFromFile(FILE *file)
|
||||
|
||||
Return a C :c:type:`long` from the data stream in a :c:type:`FILE*` opened
|
||||
Return a C :c:expr:`long` from the data stream in a :c:expr:`FILE*` opened
|
||||
for reading. Only a 32-bit value can be read in using this function,
|
||||
regardless of the native size of :c:type:`long`.
|
||||
regardless of the native size of :c:expr:`long`.
|
||||
|
||||
On error, sets the appropriate exception (:exc:`EOFError`) and returns
|
||||
``-1``.
|
||||
|
|
@ -53,9 +53,9 @@ The following functions allow marshalled values to be read back in.
|
|||
|
||||
.. c:function:: int PyMarshal_ReadShortFromFile(FILE *file)
|
||||
|
||||
Return a C :c:type:`short` from the data stream in a :c:type:`FILE*` opened
|
||||
Return a C :c:expr:`short` from the data stream in a :c:expr:`FILE*` opened
|
||||
for reading. Only a 16-bit value can be read in using this function,
|
||||
regardless of the native size of :c:type:`short`.
|
||||
regardless of the native size of :c:expr:`short`.
|
||||
|
||||
On error, sets the appropriate exception (:exc:`EOFError`) and returns
|
||||
``-1``.
|
||||
|
|
@ -63,7 +63,7 @@ The following functions allow marshalled values to be read back in.
|
|||
|
||||
.. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file)
|
||||
|
||||
Return a Python object from the data stream in a :c:type:`FILE*` opened for
|
||||
Return a Python object from the data stream in a :c:expr:`FILE*` opened for
|
||||
reading.
|
||||
|
||||
On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
|
||||
|
|
@ -72,7 +72,7 @@ The following functions allow marshalled values to be read back in.
|
|||
|
||||
.. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file)
|
||||
|
||||
Return a Python object from the data stream in a :c:type:`FILE*` opened for
|
||||
Return a Python object from the data stream in a :c:expr:`FILE*` opened for
|
||||
reading. Unlike :c:func:`PyMarshal_ReadObjectFromFile`, this function
|
||||
assumes that no further objects will be read from the file, allowing it to
|
||||
aggressively load file data into memory so that the de-serialization can
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ memory manager. For example, this is required when the interpreter is extended
|
|||
with new object types written in C. Another reason for using the Python heap is
|
||||
the desire to *inform* the Python memory manager about the memory needs of the
|
||||
extension module. Even when the requested memory is used exclusively for
|
||||
internal, highly-specific purposes, delegating all memory requests to the Python
|
||||
internal, highly specific purposes, delegating all memory requests to the Python
|
||||
memory manager causes the interpreter to have a more accurate image of its
|
||||
memory footprint as a whole. Consequently, under certain circumstances, the
|
||||
Python memory manager may or may not trigger appropriate actions, like garbage
|
||||
|
|
@ -95,6 +95,8 @@ for the I/O buffer escapes completely the Python memory manager.
|
|||
Allocator Domains
|
||||
=================
|
||||
|
||||
.. _allocator-domains:
|
||||
|
||||
All allocating functions belong to one of three different "domains" (see also
|
||||
:c:type:`PyMemAllocatorDomain`). These domains represent different allocation
|
||||
strategies and are optimized for different purposes. The specific details on
|
||||
|
|
@ -141,7 +143,7 @@ zero bytes.
|
|||
|
||||
.. c:function:: void* PyMem_RawMalloc(size_t n)
|
||||
|
||||
Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
|
||||
Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the
|
||||
allocated memory, or ``NULL`` if the request fails.
|
||||
|
||||
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
|
||||
|
|
@ -152,7 +154,7 @@ zero bytes.
|
|||
.. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize)
|
||||
|
||||
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
|
||||
a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
|
||||
a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
|
||||
request fails. The memory is initialized to zeros.
|
||||
|
||||
Requesting zero elements or elements of size zero bytes returns a distinct
|
||||
|
|
@ -212,7 +214,7 @@ The :ref:`default memory allocator <default-memory-allocators>` uses the
|
|||
|
||||
.. c:function:: void* PyMem_Malloc(size_t n)
|
||||
|
||||
Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
|
||||
Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the
|
||||
allocated memory, or ``NULL`` if the request fails.
|
||||
|
||||
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
|
||||
|
|
@ -223,7 +225,7 @@ The :ref:`default memory allocator <default-memory-allocators>` uses the
|
|||
.. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize)
|
||||
|
||||
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
|
||||
a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
|
||||
a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
|
||||
request fails. The memory is initialized to zeros.
|
||||
|
||||
Requesting zero elements or elements of size zero bytes returns a distinct
|
||||
|
|
@ -265,14 +267,14 @@ The following type-oriented macros are provided for convenience. Note that
|
|||
.. c:function:: TYPE* PyMem_New(TYPE, size_t n)
|
||||
|
||||
Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of
|
||||
memory. Returns a pointer cast to :c:type:`TYPE*`. The memory will not have
|
||||
memory. Returns a pointer cast to :c:expr:`TYPE*`. The memory will not have
|
||||
been initialized in any way.
|
||||
|
||||
|
||||
.. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n)
|
||||
|
||||
Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n *
|
||||
sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE*`. On return,
|
||||
sizeof(TYPE))`` bytes. Returns a pointer cast to :c:expr:`TYPE*`. On return,
|
||||
*p* will be a pointer to the new memory area, or ``NULL`` in the event of
|
||||
failure.
|
||||
|
||||
|
|
@ -306,7 +308,7 @@ memory from the Python heap.
|
|||
|
||||
.. note::
|
||||
There is no guarantee that the memory returned by these allocators can be
|
||||
successfully casted to a Python object when intercepting the allocating
|
||||
successfully cast to a Python object when intercepting the allocating
|
||||
functions in this domain by the methods described in
|
||||
the :ref:`Customize Memory Allocators <customize-memory-allocators>` section.
|
||||
|
||||
|
|
@ -320,7 +322,7 @@ The :ref:`default object allocator <default-memory-allocators>` uses the
|
|||
|
||||
.. c:function:: void* PyObject_Malloc(size_t n)
|
||||
|
||||
Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the
|
||||
Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the
|
||||
allocated memory, or ``NULL`` if the request fails.
|
||||
|
||||
Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as
|
||||
|
|
@ -331,7 +333,7 @@ The :ref:`default object allocator <default-memory-allocators>` uses the
|
|||
.. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize)
|
||||
|
||||
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
|
||||
a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the
|
||||
a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
|
||||
request fails. The memory is initialized to zeros.
|
||||
|
||||
Requesting zero elements or elements of size zero bytes returns a distinct
|
||||
|
|
@ -403,7 +405,7 @@ Customize Memory Allocators
|
|||
.. c:type:: PyMemAllocatorEx
|
||||
|
||||
Structure used to describe a memory block allocator. The structure has
|
||||
four fields:
|
||||
the following fields:
|
||||
|
||||
+----------------------------------------------------------+---------------------------------------+
|
||||
| Field | Meaning |
|
||||
|
|
@ -479,6 +481,25 @@ Customize Memory Allocators
|
|||
See also :c:member:`PyPreConfig.allocator` and :ref:`Preinitialize Python
|
||||
with PyPreConfig <c-preinit>`.
|
||||
|
||||
.. warning::
|
||||
|
||||
:c:func:`PyMem_SetAllocator` does have the following contract:
|
||||
|
||||
* It can be called after :c:func:`Py_PreInitialize` and before
|
||||
:c:func:`Py_InitializeFromConfig` to install a custom memory
|
||||
allocator. There are no restrictions over the installed allocator
|
||||
other than the ones imposed by the domain (for instance, the Raw
|
||||
Domain allows the allocator to be called without the GIL held). See
|
||||
:ref:`the section on allocator domains <allocator-domains>` for more
|
||||
information.
|
||||
|
||||
* If called after Python has finish initializing (after
|
||||
:c:func:`Py_InitializeFromConfig` has been called) the allocator
|
||||
**must** wrap the existing allocator. Substituting the current
|
||||
allocator for some other arbitrary one is **not supported**.
|
||||
|
||||
|
||||
|
||||
.. c:function:: void PyMem_SetupDebugHooks(void)
|
||||
|
||||
Setup :ref:`debug hooks in the Python memory allocators <pymem-debug-hooks>`
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ any other object.
|
|||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. c:function:: PyObject *PyMemoryView_FromBuffer(Py_buffer *view)
|
||||
.. c:function:: PyObject *PyMemoryView_FromBuffer(const Py_buffer *view)
|
||||
|
||||
Create a memoryview object wrapping the given buffer structure *view*.
|
||||
For simple byte buffers, :c:func:`PyMemoryView_FromMemory` is the preferred
|
||||
|
|
@ -55,10 +55,9 @@ any other object.
|
|||
*mview* **must** be a memoryview instance; this macro doesn't check its type,
|
||||
you must do it yourself or you will risk crashes.
|
||||
|
||||
.. c:function:: Py_buffer *PyMemoryView_GET_BASE(PyObject *mview)
|
||||
.. c:function:: PyObject *PyMemoryView_GET_BASE(PyObject *mview)
|
||||
|
||||
Return either a pointer to the exporting object that the memoryview is based
|
||||
on or ``NULL`` if the memoryview has been created by one of the functions
|
||||
:c:func:`PyMemoryView_FromMemory` or :c:func:`PyMemoryView_FromBuffer`.
|
||||
*mview* **must** be a memoryview instance.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ to bind a :c:data:`PyCFunction` to a class object. It replaces the former call
|
|||
|
||||
.. c:function:: PyObject* PyInstanceMethod_New(PyObject *func)
|
||||
|
||||
Return a new instance method object, with *func* being any callable object
|
||||
Return a new instance method object, with *func* being any callable object.
|
||||
*func* is the function that will be called when the instance method is
|
||||
called.
|
||||
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ Module Objects
|
|||
If *module* is not a module object (or a subtype of a module object),
|
||||
:exc:`SystemError` is raised and ``NULL`` is returned.
|
||||
|
||||
It is recommended extensions use other :c:func:`PyModule_\*` and
|
||||
:c:func:`PyObject_\*` functions rather than directly manipulate a module's
|
||||
It is recommended extensions use other ``PyModule_*`` and
|
||||
``PyObject_*`` functions rather than directly manipulate a module's
|
||||
:attr:`~object.__dict__`.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Number Protocol
|
|||
.. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2)
|
||||
|
||||
Return the floor of *o1* divided by *o2*, or ``NULL`` on failure. This is
|
||||
equivalent to the "classic" division of integers.
|
||||
the equivalent of the Python expression ``o1 // o2``.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2)
|
||||
|
|
@ -53,7 +53,7 @@ Number Protocol
|
|||
*o2*, or ``NULL`` on failure. The return value is "approximate" because binary
|
||||
floating point numbers are approximate; it is not possible to represent all real
|
||||
numbers in base two. This function can return a floating point value when
|
||||
passed two integers.
|
||||
passed two integers. This is the equivalent of the Python expression ``o1 / o2``.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2)
|
||||
|
|
@ -180,6 +180,7 @@ Number Protocol
|
|||
floating point numbers are approximate; it is not possible to represent all real
|
||||
numbers in base two. This function can return a floating point value when
|
||||
passed two integers. The operation is done *in-place* when *o1* supports it.
|
||||
This is the equivalent of the Python statement ``o1 /= o2``.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2)
|
||||
|
|
@ -272,11 +273,11 @@ Number Protocol
|
|||
|
||||
.. c:function:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc)
|
||||
|
||||
Returns *o* converted to a Py_ssize_t value if *o* can be interpreted as an
|
||||
Returns *o* converted to a :c:type:`Py_ssize_t` value if *o* can be interpreted as an
|
||||
integer. If the call fails, an exception is raised and ``-1`` is returned.
|
||||
|
||||
If *o* can be converted to a Python int but the attempt to
|
||||
convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the
|
||||
convert to a :c:type:`Py_ssize_t` value would raise an :exc:`OverflowError`, then the
|
||||
*exc* argument is the type of exception that will be raised (usually
|
||||
:exc:`IndexError` or :exc:`OverflowError`). If *exc* is ``NULL``, then the
|
||||
exception is cleared and the value is clipped to ``PY_SSIZE_T_MIN`` for a negative
|
||||
|
|
@ -285,6 +286,6 @@ Number Protocol
|
|||
|
||||
.. c:function:: int PyIndex_Check(PyObject *o)
|
||||
|
||||
Returns ``1`` if *o* is an index integer (has the nb_index slot of the
|
||||
tp_as_number structure filled in), and ``0`` otherwise.
|
||||
Returns ``1`` if *o* is an index integer (has the ``nb_index`` slot of the
|
||||
``tp_as_number`` structure filled in), and ``0`` otherwise.
|
||||
This function always succeeds.
|
||||
|
|
|
|||
|
|
@ -81,8 +81,9 @@ Object Protocol
|
|||
return ``0`` on success. This is the equivalent of the Python statement
|
||||
``o.attr_name = v``.
|
||||
|
||||
If *v* is ``NULL``, the attribute is deleted, however this feature is
|
||||
deprecated in favour of using :c:func:`PyObject_DelAttr`.
|
||||
If *v* is ``NULL``, the attribute is deleted. This behaviour is deprecated
|
||||
in favour of using :c:func:`PyObject_DelAttr`, but there are currently no
|
||||
plans to remove it.
|
||||
|
||||
|
||||
.. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
|
||||
|
|
@ -92,7 +93,7 @@ Object Protocol
|
|||
return ``0`` on success. This is the equivalent of the Python statement
|
||||
``o.attr_name = v``.
|
||||
|
||||
If *v* is ``NULL``, the attribute is deleted, however this feature is
|
||||
If *v* is ``NULL``, the attribute is deleted, but this feature is
|
||||
deprecated in favour of using :c:func:`PyObject_DelAttrString`.
|
||||
|
||||
|
||||
|
|
@ -125,6 +126,14 @@ Object Protocol
|
|||
A generic implementation for the getter of a ``__dict__`` descriptor. It
|
||||
creates the dictionary if necessary.
|
||||
|
||||
This function may also be called to get the :py:attr:`~object.__dict__`
|
||||
of the object *o*. Pass ``NULL`` for *context* when calling it.
|
||||
Since this function may need to allocate memory for the
|
||||
dictionary, it may be more efficient to call :c:func:`PyObject_GetAttr`
|
||||
when accessing an attribute on the object.
|
||||
|
||||
On failure, returns ``NULL`` with an exception set.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
|
|
@ -136,6 +145,16 @@ Object Protocol
|
|||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
.. c:function:: PyObject** _PyObject_GetDictPtr(PyObject *obj)
|
||||
|
||||
Return a pointer to :py:attr:`~object.__dict__` of the object *obj*.
|
||||
If there is no ``__dict__``, return ``NULL`` without setting an exception.
|
||||
|
||||
This function may need to allocate memory for the
|
||||
dictionary, so it may be more efficient to call :c:func:`PyObject_GetAttr`
|
||||
when accessing an attribute on the object.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)
|
||||
|
||||
Compare the values of *o1* and *o2* using the operation specified by *opid*,
|
||||
|
|
@ -257,7 +276,7 @@ Object Protocol
|
|||
|
||||
.. versionchanged:: 3.2
|
||||
The return type is now Py_hash_t. This is a signed integer the same size
|
||||
as Py_ssize_t.
|
||||
as :c:type:`Py_ssize_t`.
|
||||
|
||||
|
||||
.. c:function:: Py_hash_t PyObject_HashNotImplemented(PyObject *o)
|
||||
|
|
@ -290,8 +309,8 @@ Object Protocol
|
|||
of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``. This
|
||||
is equivalent to the Python expression ``type(o)``. This function increments the
|
||||
reference count of the return value. There's really no reason to use this
|
||||
function instead of the common expression ``o->ob_type``, which returns a
|
||||
pointer of type :c:type:`PyTypeObject*`, except when the incremented reference
|
||||
function instead of the :c:func:`Py_TYPE()` function, which returns a
|
||||
pointer of type :c:expr:`PyTypeObject*`, except when the incremented reference
|
||||
count is needed.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,28 @@
|
|||
Reference Counting
|
||||
******************
|
||||
|
||||
The macros in this section are used for managing reference counts of Python
|
||||
objects.
|
||||
The functions and macros in this section are used for managing reference counts
|
||||
of Python objects.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t Py_REFCNT(PyObject *o)
|
||||
|
||||
Get the reference count of the Python object *o*.
|
||||
|
||||
Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
The parameter type is no longer :c:expr:`const PyObject*`.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
:c:func:`Py_REFCNT()` is changed to the inline static function.
|
||||
|
||||
|
||||
.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)
|
||||
|
||||
Set the object *o* reference counter to *refcnt*.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: void Py_INCREF(PyObject *o)
|
||||
|
|
@ -109,13 +129,55 @@ objects.
|
|||
It is a good idea to use this macro whenever decrementing the reference
|
||||
count of an object that might be traversed during garbage collection.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The macro argument is now only evaluated once. If the argument has side
|
||||
effects, these are no longer duplicated.
|
||||
|
||||
The following functions are for runtime dynamic embedding of Python:
|
||||
``Py_IncRef(PyObject *o)``, ``Py_DecRef(PyObject *o)``. They are
|
||||
simply exported function versions of :c:func:`Py_XINCREF` and
|
||||
:c:func:`Py_XDECREF`, respectively.
|
||||
|
||||
The following functions or macros are only for use within the interpreter core:
|
||||
:c:func:`_Py_Dealloc`, :c:func:`_Py_ForgetReference`, :c:func:`_Py_NewReference`,
|
||||
as well as the global variable :c:data:`_Py_RefTotal`.
|
||||
.. c:function:: void Py_IncRef(PyObject *o)
|
||||
|
||||
Increment the reference count for object *o*. A function version of :c:func:`Py_XINCREF`.
|
||||
It can be used for runtime dynamic embedding of Python.
|
||||
|
||||
|
||||
.. c:function:: void Py_DecRef(PyObject *o)
|
||||
|
||||
Decrement the reference count for object *o*. A function version of :c:func:`Py_XDECREF`.
|
||||
It can be used for runtime dynamic embedding of Python.
|
||||
|
||||
|
||||
.. c:macro:: Py_SETREF(dst, src)
|
||||
|
||||
Macro safely decrementing the `dst` reference count and setting `dst` to
|
||||
`src`.
|
||||
|
||||
As in case of :c:func:`Py_CLEAR`, "the obvious" code can be deadly::
|
||||
|
||||
Py_DECREF(dst);
|
||||
dst = src;
|
||||
|
||||
The safe way is::
|
||||
|
||||
Py_SETREF(dst, src);
|
||||
|
||||
That arranges to set `dst` to `src` _before_ decrementing reference count of
|
||||
*dst* old value, so that any code triggered as a side-effect of `dst`
|
||||
getting torn down no longer believes `dst` points to a valid object.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The macro arguments are now only evaluated once. If an argument has side
|
||||
effects, these are no longer duplicated.
|
||||
|
||||
|
||||
.. c:macro:: Py_XSETREF(dst, src)
|
||||
|
||||
Variant of :c:macro:`Py_SETREF` macro that uses :c:func:`Py_XDECREF` instead
|
||||
of :c:func:`Py_DECREF`.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The macro arguments are now only evaluated once. If an argument has side
|
||||
effects, these are no longer duplicated.
|
||||
|
|
|
|||
|
|
@ -31,35 +31,6 @@ Reflection
|
|||
See also :c:func:`PyThreadState_GetFrame`.
|
||||
|
||||
|
||||
.. c:function:: int PyFrame_GetBack(PyFrameObject *frame)
|
||||
|
||||
Get the *frame* next outer frame.
|
||||
|
||||
Return a :term:`strong reference`, or ``NULL`` if *frame* has no outer frame.
|
||||
|
||||
*frame* must not be ``NULL``.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: int PyFrame_GetCode(PyFrameObject *frame)
|
||||
|
||||
Get the *frame* code.
|
||||
|
||||
Return a :term:`strong reference`.
|
||||
|
||||
*frame* must not be ``NULL``. The result (frame code) cannot be ``NULL``.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame)
|
||||
|
||||
Return the line number that *frame* is currently executing.
|
||||
|
||||
*frame* must not be ``NULL``.
|
||||
|
||||
|
||||
.. c:function:: const char* PyEval_GetFuncName(PyObject *func)
|
||||
|
||||
Return the name of *func* if it is a function, class or instance object, else the
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ Sequence Protocol
|
|||
|
||||
.. c:function:: int PySequence_Check(PyObject *o)
|
||||
|
||||
Return ``1`` if the object provides sequence protocol, and ``0`` otherwise.
|
||||
Return ``1`` if the object provides the sequence protocol, and ``0`` otherwise.
|
||||
Note that it returns ``1`` for Python classes with a :meth:`__getitem__`
|
||||
method unless they are :class:`dict` subclasses since in general case it
|
||||
is impossible to determine what the type of keys it supports. This
|
||||
method, unless they are :class:`dict` subclasses, since in general it
|
||||
is impossible to determine what type of keys the class supports. This
|
||||
function always succeeds.
|
||||
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ Sequence Protocol
|
|||
is the equivalent of the Python statement ``o[i] = v``. This function *does
|
||||
not* steal a reference to *v*.
|
||||
|
||||
If *v* is ``NULL``, the element is deleted, however this feature is
|
||||
If *v* is ``NULL``, the element is deleted, but this feature is
|
||||
deprecated in favour of using :c:func:`PySequence_DelItem`.
|
||||
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ Sequence Protocol
|
|||
|
||||
Returns the length of *o*, assuming that *o* was returned by
|
||||
:c:func:`PySequence_Fast` and that *o* is not ``NULL``. The size can also be
|
||||
gotten by calling :c:func:`PySequence_Size` on *o*, but
|
||||
retrieved by calling :c:func:`PySequence_Size` on *o*, but
|
||||
:c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a
|
||||
list or tuple.
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Set Objects
|
|||
object: frozenset
|
||||
|
||||
This section details the public API for :class:`set` and :class:`frozenset`
|
||||
objects. Any functionality not listed below is best accessed using the either
|
||||
objects. Any functionality not listed below is best accessed using either
|
||||
the abstract object protocol (including :c:func:`PyObject_CallMethod`,
|
||||
:c:func:`PyObject_RichCompareBool`, :c:func:`PyObject_Hash`,
|
||||
:c:func:`PyObject_Repr`, :c:func:`PyObject_IsTrue`, :c:func:`PyObject_Print`, and
|
||||
|
|
@ -31,7 +31,7 @@ the abstract object protocol (including :c:func:`PyObject_CallMethod`,
|
|||
in that it is a fixed size for small sets (much like tuple storage) and will
|
||||
point to a separate, variable sized block of memory for medium and large sized
|
||||
sets (much like list storage). None of the fields of this structure should be
|
||||
considered public and are subject to change. All access should be done through
|
||||
considered public and all are subject to change. All access should be done through
|
||||
the documented API rather than by manipulating the values in the structure.
|
||||
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ or :class:`frozenset` or instances of their subtypes.
|
|||
.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
|
||||
|
||||
Add *key* to a :class:`set` instance. Also works with :class:`frozenset`
|
||||
instances (like :c:func:`PyTuple_SetItem` it can be used to fill-in the values
|
||||
instances (like :c:func:`PyTuple_SetItem` it can be used to fill in the values
|
||||
of brand new frozensets before they are exposed to other code). Return ``0`` on
|
||||
success or ``-1`` on failure. Raise a :exc:`TypeError` if the *key* is
|
||||
unhashable. Raise a :exc:`MemoryError` if there is no room to grow. Raise a
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ All Python objects ultimately share a small number of fields at the beginning
|
|||
of the object's representation in memory. These are represented by the
|
||||
:c:type:`PyObject` and :c:type:`PyVarObject` types, which are defined, in turn,
|
||||
by the expansions of some macros also used, whether directly or indirectly, in
|
||||
the definition of all other Python objects.
|
||||
the definition of all other Python objects. Additional macros can be found
|
||||
under :ref:`reference counting <countingrefs>`.
|
||||
|
||||
|
||||
.. c:type:: PyObject
|
||||
|
|
@ -27,7 +28,7 @@ the definition of all other Python objects.
|
|||
object. In a normal "release" build, it contains only the object's
|
||||
reference count and a pointer to the corresponding type object.
|
||||
Nothing is actually declared to be a :c:type:`PyObject`, but every pointer
|
||||
to a Python object can be cast to a :c:type:`PyObject*`. Access to the
|
||||
to a Python object can be cast to a :c:expr:`PyObject*`. Access to the
|
||||
members must be done by using the macros :c:macro:`Py_REFCNT` and
|
||||
:c:macro:`Py_TYPE`.
|
||||
|
||||
|
|
@ -62,14 +63,14 @@ the definition of all other Python objects.
|
|||
See documentation of :c:type:`PyVarObject` above.
|
||||
|
||||
|
||||
.. c:function:: int Py_Is(const PyObject *x, const PyObject *y)
|
||||
.. c:function:: int Py_Is(PyObject *x, PyObject *y)
|
||||
|
||||
Test if the *x* object is the *y* object, the same as ``x is y`` in Python.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
|
||||
.. c:function:: int Py_IsNone(const PyObject *x)
|
||||
.. c:function:: int Py_IsNone(PyObject *x)
|
||||
|
||||
Test if an object is the ``None`` singleton,
|
||||
the same as ``x is None`` in Python.
|
||||
|
|
@ -77,7 +78,7 @@ the definition of all other Python objects.
|
|||
.. versionadded:: 3.10
|
||||
|
||||
|
||||
.. c:function:: int Py_IsTrue(const PyObject *x)
|
||||
.. c:function:: int Py_IsTrue(PyObject *x)
|
||||
|
||||
Test if an object is the ``True`` singleton,
|
||||
the same as ``x is True`` in Python.
|
||||
|
|
@ -85,7 +86,7 @@ the definition of all other Python objects.
|
|||
.. versionadded:: 3.10
|
||||
|
||||
|
||||
.. c:function:: int Py_IsFalse(const PyObject *x)
|
||||
.. c:function:: int Py_IsFalse(PyObject *x)
|
||||
|
||||
Test if an object is the ``False`` singleton,
|
||||
the same as ``x is False`` in Python.
|
||||
|
|
@ -93,7 +94,7 @@ the definition of all other Python objects.
|
|||
.. versionadded:: 3.10
|
||||
|
||||
|
||||
.. c:function:: PyTypeObject* Py_TYPE(const PyObject *o)
|
||||
.. c:function:: PyTypeObject* Py_TYPE(PyObject *o)
|
||||
|
||||
Get the type of the Python object *o*.
|
||||
|
||||
|
|
@ -103,6 +104,7 @@ the definition of all other Python objects.
|
|||
|
||||
.. versionchanged:: 3.11
|
||||
:c:func:`Py_TYPE()` is changed to an inline static function.
|
||||
The parameter type is no longer :c:expr:`const PyObject*`.
|
||||
|
||||
|
||||
.. c:function:: int Py_IS_TYPE(PyObject *o, PyTypeObject *type)
|
||||
|
|
@ -120,24 +122,7 @@ the definition of all other Python objects.
|
|||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t Py_REFCNT(const PyObject *o)
|
||||
|
||||
Get the reference count of the Python object *o*.
|
||||
|
||||
Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
:c:func:`Py_REFCNT()` is changed to the inline static function.
|
||||
|
||||
|
||||
.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)
|
||||
|
||||
Set the object *o* reference counter to *refcnt*.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t Py_SIZE(const PyVarObject *o)
|
||||
.. c:function:: Py_ssize_t Py_SIZE(PyVarObject *o)
|
||||
|
||||
Get the size of the Python object *o*.
|
||||
|
||||
|
|
@ -145,6 +130,7 @@ the definition of all other Python objects.
|
|||
|
||||
.. versionchanged:: 3.11
|
||||
:c:func:`Py_SIZE()` is changed to an inline static function.
|
||||
The parameter type is no longer :c:expr:`const PyVarObject*`.
|
||||
|
||||
|
||||
.. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)
|
||||
|
|
@ -179,7 +165,7 @@ Implementing functions and methods
|
|||
.. c:type:: PyCFunction
|
||||
|
||||
Type of the functions used to implement most Python callables in C.
|
||||
Functions of this type take two :c:type:`PyObject*` parameters and return
|
||||
Functions of this type take two :c:expr:`PyObject*` parameters and return
|
||||
one such value. If the return value is ``NULL``, an exception shall have
|
||||
been set. If not ``NULL``, the return value is interpreted as the return
|
||||
value of the function as exposed in Python. The function must return a new
|
||||
|
|
@ -242,29 +228,30 @@ Implementing functions and methods
|
|||
Structure used to describe a method of an extension type. This structure has
|
||||
four fields:
|
||||
|
||||
+------------------+---------------+-------------------------------+
|
||||
| Field | C Type | Meaning |
|
||||
+==================+===============+===============================+
|
||||
| :attr:`ml_name` | const char \* | name of the method |
|
||||
+------------------+---------------+-------------------------------+
|
||||
| :attr:`ml_meth` | PyCFunction | pointer to the C |
|
||||
| | | implementation |
|
||||
+------------------+---------------+-------------------------------+
|
||||
| :attr:`ml_flags` | int | flag bits indicating how the |
|
||||
| | | call should be constructed |
|
||||
+------------------+---------------+-------------------------------+
|
||||
| :attr:`ml_doc` | const char \* | points to the contents of the |
|
||||
| | | docstring |
|
||||
+------------------+---------------+-------------------------------+
|
||||
.. c:member:: const char* ml_name
|
||||
|
||||
The :attr:`ml_meth` is a C function pointer. The functions may be of different
|
||||
types, but they always return :c:type:`PyObject*`. If the function is not of
|
||||
name of the method
|
||||
|
||||
.. c:member:: PyCFunction ml_meth
|
||||
|
||||
pointer to the C implementation
|
||||
|
||||
.. c:member:: int ml_flags
|
||||
|
||||
flags bits indicating how the call should be constructed
|
||||
|
||||
.. c:member:: const char* ml_doc
|
||||
|
||||
points to the contents of the docstring
|
||||
|
||||
The :c:member:`ml_meth` is a C function pointer. The functions may be of different
|
||||
types, but they always return :c:expr:`PyObject*`. If the function is not of
|
||||
the :c:type:`PyCFunction`, the compiler will require a cast in the method table.
|
||||
Even though :c:type:`PyCFunction` defines the first parameter as
|
||||
:c:type:`PyObject*`, it is common that the method implementation uses the
|
||||
:c:expr:`PyObject*`, it is common that the method implementation uses the
|
||||
specific C type of the *self* object.
|
||||
|
||||
The :attr:`ml_flags` field is a bitfield which can include the following flags.
|
||||
The :c:member:`ml_flags` field is a bitfield which can include the following flags.
|
||||
The individual flags indicate either a calling convention or a binding
|
||||
convention.
|
||||
|
||||
|
|
@ -273,7 +260,7 @@ There are these calling conventions:
|
|||
.. data:: METH_VARARGS
|
||||
|
||||
This is the typical calling convention, where the methods have the type
|
||||
:c:type:`PyCFunction`. The function expects two :c:type:`PyObject*` values.
|
||||
:c:type:`PyCFunction`. The function expects two :c:expr:`PyObject*` values.
|
||||
The first one is the *self* object for methods; for module functions, it is
|
||||
the module object. The second parameter (often called *args*) is a tuple
|
||||
object representing all arguments. This parameter is typically processed
|
||||
|
|
@ -294,7 +281,7 @@ There are these calling conventions:
|
|||
Fast calling convention supporting only positional arguments.
|
||||
The methods have the type :c:type:`_PyCFunctionFast`.
|
||||
The first parameter is *self*, the second parameter is a C array
|
||||
of :c:type:`PyObject*` values indicating the arguments and the third
|
||||
of :c:expr:`PyObject*` values indicating the arguments and the third
|
||||
parameter is the number of arguments (the length of the array).
|
||||
|
||||
.. versionadded:: 3.7
|
||||
|
|
@ -310,14 +297,12 @@ There are these calling conventions:
|
|||
with methods of type :c:type:`_PyCFunctionFastWithKeywords`.
|
||||
Keyword arguments are passed the same way as in the
|
||||
:ref:`vectorcall protocol <vectorcall>`:
|
||||
there is an additional fourth :c:type:`PyObject*` parameter
|
||||
there is an additional fourth :c:expr:`PyObject*` parameter
|
||||
which is a tuple representing the names of the keyword arguments
|
||||
(which are guaranteed to be strings)
|
||||
or possibly ``NULL`` if there are no keywords. The values of the keyword
|
||||
arguments are stored in the *args* array, after the positional arguments.
|
||||
|
||||
This is not part of the :ref:`limited API <stable>`.
|
||||
|
||||
.. versionadded:: 3.7
|
||||
|
||||
|
||||
|
|
@ -342,13 +327,16 @@ There are these calling conventions:
|
|||
hold a reference to the module or object instance. In all cases the second
|
||||
parameter will be ``NULL``.
|
||||
|
||||
The function must have 2 parameters. Since the second parameter is unused,
|
||||
:c:macro:`Py_UNUSED` can be used to prevent a compiler warning.
|
||||
|
||||
|
||||
.. data:: METH_O
|
||||
|
||||
Methods with a single object argument can be listed with the :const:`METH_O`
|
||||
flag, instead of invoking :c:func:`PyArg_ParseTuple` with a ``"O"`` argument.
|
||||
They have the type :c:type:`PyCFunction`, with the *self* parameter, and a
|
||||
:c:type:`PyObject*` parameter representing the single argument.
|
||||
:c:expr:`PyObject*` parameter representing the single argument.
|
||||
|
||||
|
||||
These two constants are not used to indicate the calling convention but the
|
||||
|
|
@ -398,84 +386,67 @@ Accessing attributes of extension types
|
|||
.. c:type:: PyMemberDef
|
||||
|
||||
Structure which describes an attribute of a type which corresponds to a C
|
||||
struct member. Its fields are:
|
||||
struct member. Its fields are, in order:
|
||||
|
||||
+------------------+---------------+-------------------------------+
|
||||
| Field | C Type | Meaning |
|
||||
+==================+===============+===============================+
|
||||
| :attr:`name` | const char \* | name of the member |
|
||||
+------------------+---------------+-------------------------------+
|
||||
| :attr:`!type` | int | the type of the member in the |
|
||||
| | | C struct |
|
||||
+------------------+---------------+-------------------------------+
|
||||
| :attr:`offset` | Py_ssize_t | the offset in bytes that the |
|
||||
| | | member is located on the |
|
||||
| | | type's object struct |
|
||||
+------------------+---------------+-------------------------------+
|
||||
| :attr:`flags` | int | flag bits indicating if the |
|
||||
| | | field should be read-only or |
|
||||
| | | writable |
|
||||
+------------------+---------------+-------------------------------+
|
||||
| :attr:`doc` | const char \* | points to the contents of the |
|
||||
| | | docstring |
|
||||
+------------------+---------------+-------------------------------+
|
||||
.. c:member:: const char* name
|
||||
|
||||
:attr:`!type` can be one of many ``T_`` macros corresponding to various C
|
||||
types. When the member is accessed in Python, it will be converted to the
|
||||
equivalent Python type.
|
||||
Name of the member.
|
||||
A NULL value marks the end of a ``PyMemberDef[]`` array.
|
||||
|
||||
=============== ==================
|
||||
Macro name C type
|
||||
=============== ==================
|
||||
T_SHORT short
|
||||
T_INT int
|
||||
T_LONG long
|
||||
T_FLOAT float
|
||||
T_DOUBLE double
|
||||
T_STRING const char \*
|
||||
T_OBJECT PyObject \*
|
||||
T_OBJECT_EX PyObject \*
|
||||
T_CHAR char
|
||||
T_BYTE char
|
||||
T_UBYTE unsigned char
|
||||
T_UINT unsigned int
|
||||
T_USHORT unsigned short
|
||||
T_ULONG unsigned long
|
||||
T_BOOL char
|
||||
T_LONGLONG long long
|
||||
T_ULONGLONG unsigned long long
|
||||
T_PYSSIZET Py_ssize_t
|
||||
=============== ==================
|
||||
The string should be static, no copy is made of it.
|
||||
|
||||
:c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX` differ in that
|
||||
:c:macro:`T_OBJECT` returns ``None`` if the member is ``NULL`` and
|
||||
:c:macro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use
|
||||
:c:macro:`T_OBJECT_EX` over :c:macro:`T_OBJECT` because :c:macro:`T_OBJECT_EX`
|
||||
handles use of the :keyword:`del` statement on that attribute more correctly
|
||||
than :c:macro:`T_OBJECT`.
|
||||
.. c:member:: Py_ssize_t PyMemberDef.offset
|
||||
|
||||
: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`. :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``).
|
||||
The offset in bytes that the member is located on the type’s object struct.
|
||||
|
||||
.. c:member:: int type
|
||||
|
||||
The type of the member in the C struct.
|
||||
See :ref:`PyMemberDef-types` for the possible values.
|
||||
|
||||
.. c:member:: int flags
|
||||
|
||||
Zero or more of the :ref:`PyMemberDef-flags`, combined using bitwise OR.
|
||||
|
||||
.. c:member:: const char* doc
|
||||
|
||||
The docstring, or NULL.
|
||||
The string should be static, no copy is made of it.
|
||||
Typically, it is defined using :c:macro:`PyDoc_STR`.
|
||||
|
||||
By default (when :c:member:`flags` is ``0``), members allow
|
||||
both read and write access.
|
||||
Use the :c:macro:`Py_READONLY` flag for read-only access.
|
||||
Certain types, like :c:macro:`Py_T_STRING`, imply :c:macro:`Py_READONLY`.
|
||||
Only :c:macro:`Py_T_OBJECT_EX` (and legacy :c:macro:`T_OBJECT`) members can
|
||||
be deleted.
|
||||
|
||||
.. _pymemberdef-offsets:
|
||||
|
||||
Heap allocated types (created using :c:func:`PyType_FromSpec` or similar),
|
||||
``PyMemberDef`` may contain definitions for the special members
|
||||
``__dictoffset__``, ``__weaklistoffset__`` and ``__vectorcalloffset__``,
|
||||
corresponding to
|
||||
:c:member:`~PyTypeObject.tp_dictoffset`,
|
||||
:c:member:`~PyTypeObject.tp_weaklistoffset` and
|
||||
For heap-allocated types (created using :c:func:`PyType_FromSpec` or similar),
|
||||
``PyMemberDef`` may contain a definition for the special member
|
||||
``"__vectorcalloffset__"``, corresponding to
|
||||
:c:member:`~PyTypeObject.tp_vectorcall_offset` in type objects.
|
||||
These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example::
|
||||
These must be defined with ``Py_T_PYSSIZET`` and ``Py_READONLY``, for example::
|
||||
|
||||
static PyMemberDef spam_type_members[] = {
|
||||
{"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY},
|
||||
{"__vectorcalloffset__", Py_T_PYSSIZET,
|
||||
offsetof(Spam_object, vectorcall), Py_READONLY},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
(You may need to ``#include <stddef.h>`` for :c:func:`!offsetof`.)
|
||||
|
||||
The legacy offsets :c:member:`~PyTypeObject.tp_dictoffset` and
|
||||
:c:member:`~PyTypeObject.tp_weaklistoffset` can be defined similarly using
|
||||
``"__dictoffset__"`` and ``"__weaklistoffset__"`` members, but extensions
|
||||
are strongly encouraged to use :const:`Py_TPFLAGS_MANAGED_DICT` and
|
||||
:const:`Py_TPFLAGS_MANAGED_WEAKREF` instead.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
``PyMemberDef`` is always available.
|
||||
Previously, it required including ``"structmember.h"``.
|
||||
|
||||
.. c:function:: PyObject* PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m)
|
||||
|
||||
|
|
@ -483,6 +454,10 @@ Accessing attributes of extension types
|
|||
attribute is described by ``PyMemberDef`` *m*. Returns ``NULL``
|
||||
on error.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
``PyMember_GetOne`` is always available.
|
||||
Previously, it required including ``"structmember.h"``.
|
||||
|
||||
.. c:function:: int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o)
|
||||
|
||||
|
|
@ -490,31 +465,171 @@ Accessing attributes of extension types
|
|||
The attribute to set is described by ``PyMemberDef`` *m*. Returns ``0``
|
||||
if successful and a negative value on failure.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
``PyMember_SetOne`` is always available.
|
||||
Previously, it required including ``"structmember.h"``.
|
||||
|
||||
.. _PyMemberDef-flags:
|
||||
|
||||
Member flags
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The following flags can be used with :c:member:`PyMemberDef.flags`:
|
||||
|
||||
.. c:macro:: Py_READONLY
|
||||
|
||||
Not writable.
|
||||
|
||||
.. c:macro:: Py_AUDIT_READ
|
||||
|
||||
Emit an ``object.__getattr__`` :ref:`audit event <audit-events>`
|
||||
before reading.
|
||||
|
||||
.. index::
|
||||
single: READ_RESTRICTED
|
||||
single: WRITE_RESTRICTED
|
||||
single: RESTRICTED
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
|
||||
The :const:`!RESTRICTED`, :const:`!READ_RESTRICTED` and
|
||||
:const:`!WRITE_RESTRICTED` macros available with
|
||||
``#include "structmember.h"`` are deprecated.
|
||||
:const:`!READ_RESTRICTED` and :const:`!RESTRICTED` are equivalent to
|
||||
:const:`Py_AUDIT_READ`; :const:`!WRITE_RESTRICTED` does nothing.
|
||||
|
||||
.. index::
|
||||
single: READONLY
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
The :const:`!READONLY` macro was renamed to :const:`Py_READONLY`.
|
||||
The :const:`!PY_AUDIT_READ` macro was renamed with the ``Py_`` prefix.
|
||||
The new names are now always available.
|
||||
Previously, these required ``#include "structmember.h"``.
|
||||
The header is still available and it provides the old names.
|
||||
|
||||
.. _PyMemberDef-types:
|
||||
|
||||
Member types
|
||||
^^^^^^^^^^^^
|
||||
|
||||
:c:member:`PyMemberDef.type` can be one of the following macros corresponding
|
||||
to various C types.
|
||||
When the member is accessed in Python, it will be converted to the
|
||||
equivalent Python type.
|
||||
When it is set from Python, it will be converted back to the C type.
|
||||
If that is not possible, an exception such as :exc:`TypeError` or
|
||||
:exc:`ValueError` is raised.
|
||||
|
||||
Unless marked (D), attributes defined this way cannot be deleted
|
||||
using e.g. :keyword:`del` or :py:func:`delattr`.
|
||||
|
||||
================================ ============================= ======================
|
||||
Macro name C type Python type
|
||||
================================ ============================= ======================
|
||||
.. c:macro:: Py_T_BYTE :c:expr:`char` :py:class:`int`
|
||||
.. c:macro:: Py_T_SHORT :c:expr:`short` :py:class:`int`
|
||||
.. c:macro:: Py_T_INT :c:expr:`int` :py:class:`int`
|
||||
.. c:macro:: Py_T_LONG :c:expr:`long` :py:class:`int`
|
||||
.. c:macro:: Py_T_LONGLONG :c:expr:`long long` :py:class:`int`
|
||||
.. c:macro:: Py_T_UBYTE :c:expr:`unsigned char` :py:class:`int`
|
||||
.. c:macro:: Py_T_UINT :c:expr:`unsigned int` :py:class:`int`
|
||||
.. c:macro:: Py_T_USHORT :c:expr:`unsigned short` :py:class:`int`
|
||||
.. c:macro:: Py_T_ULONG :c:expr:`unsigned long` :py:class:`int`
|
||||
.. c:macro:: Py_T_ULONGLONG :c:expr:`unsigned long long` :py:class:`int`
|
||||
.. c:macro:: Py_T_PYSSIZET :c:expr:`Py_ssize_t` :py:class:`int`
|
||||
.. c:macro:: Py_T_FLOAT :c:expr:`float` :py:class:`float`
|
||||
.. c:macro:: Py_T_DOUBLE :c:expr:`double` :py:class:`float`
|
||||
.. c:macro:: Py_T_BOOL :c:expr:`char` :py:class:`bool`
|
||||
(written as 0 or 1)
|
||||
.. c:macro:: Py_T_STRING :c:expr:`const char *` (*) :py:class:`str` (RO)
|
||||
.. c:macro:: Py_T_STRING_INPLACE :c:expr:`const char[]` (*) :py:class:`str` (RO)
|
||||
.. c:macro:: Py_T_CHAR :c:expr:`char` (0-127) :py:class:`str` (**)
|
||||
.. c:macro:: Py_T_OBJECT_EX :c:expr:`PyObject *` :py:class:`object` (D)
|
||||
================================ ============================= ======================
|
||||
|
||||
(*): Zero-terminated, UTF8-encoded C string.
|
||||
With :c:macro:`!Py_T_STRING` the C representation is a pointer;
|
||||
with :c:macro:`!Py_T_STRING_INLINE` the string is stored directly
|
||||
in the structure.
|
||||
|
||||
(**): String of length 1. Only ASCII is accepted.
|
||||
|
||||
(RO): Implies :c:macro:`Py_READONLY`.
|
||||
|
||||
(D): Can be deleted, in which case the pointer is set to ``NULL``.
|
||||
Reading a ``NULL`` pointer raises :py:exc:`AttributeError`.
|
||||
|
||||
.. index::
|
||||
single: T_BYTE
|
||||
single: T_SHORT
|
||||
single: T_INT
|
||||
single: T_LONG
|
||||
single: T_LONGLONG
|
||||
single: T_UBYTE
|
||||
single: T_USHORT
|
||||
single: T_UINT
|
||||
single: T_ULONG
|
||||
single: T_ULONGULONG
|
||||
single: T_PYSSIZET
|
||||
single: T_FLOAT
|
||||
single: T_DOUBLE
|
||||
single: T_BOOL
|
||||
single: T_CHAR
|
||||
single: T_STRING
|
||||
single: T_STRING_INPLACE
|
||||
single: T_OBJECT_EX
|
||||
single: structmember.h
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
In previous versions, the macros were only available with
|
||||
``#include "structmember.h"`` and were named without the ``Py_`` prefix
|
||||
(e.g. as ``T_INT``).
|
||||
The header is still available and contains the old names, along with
|
||||
the following deprecated types:
|
||||
|
||||
.. c:macro:: T_OBJECT
|
||||
|
||||
Like ``Py_T_OBJECT_EX``, but ``NULL`` is converted to ``None``.
|
||||
This results in surprising behavior in Python: deleting the attribute
|
||||
effectively sets it to ``None``.
|
||||
|
||||
.. c:macro:: T_NONE
|
||||
|
||||
Always ``None``. Must be used with :c:macro:`Py_READONLY`.
|
||||
|
||||
Defining Getters and Setters
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. c:type:: PyGetSetDef
|
||||
|
||||
Structure to define property-like access for a type. See also description of
|
||||
the :c:member:`PyTypeObject.tp_getset` slot.
|
||||
|
||||
+-------------+------------------+-----------------------------------+
|
||||
| Field | C Type | Meaning |
|
||||
+=============+==================+===================================+
|
||||
| name | const char \* | attribute name |
|
||||
+-------------+------------------+-----------------------------------+
|
||||
| get | getter | C Function to get the attribute |
|
||||
+-------------+------------------+-----------------------------------+
|
||||
| set | setter | optional C function to set or |
|
||||
| | | delete the attribute, if omitted |
|
||||
| | | the attribute is readonly |
|
||||
+-------------+------------------+-----------------------------------+
|
||||
| doc | const char \* | optional docstring |
|
||||
+-------------+------------------+-----------------------------------+
|
||||
| closure | void \* | optional function pointer, |
|
||||
| | | providing additional data for |
|
||||
| | | getter and setter |
|
||||
+-------------+------------------+-----------------------------------+
|
||||
.. c:member:: const char* PyGetSetDef.name
|
||||
|
||||
The ``get`` function takes one :c:type:`PyObject*` parameter (the
|
||||
attribute name
|
||||
|
||||
.. c:member:: getter PyGetSetDef.get
|
||||
|
||||
C function to get the attribute.
|
||||
|
||||
.. c:member:: setter PyGetSetDef.set
|
||||
|
||||
Optional C function to set or delete the attribute, if omitted the attribute is readonly.
|
||||
|
||||
.. c:member:: const char* PyGetSetDef.doc
|
||||
|
||||
optional docstring
|
||||
|
||||
.. c:member:: void* PyGetSetDef.closure
|
||||
|
||||
Optional function pointer, providing additional data for getter and setter.
|
||||
|
||||
The ``get`` function takes one :c:expr:`PyObject*` parameter (the
|
||||
instance) and a function pointer (the associated ``closure``)::
|
||||
|
||||
typedef PyObject *(*getter)(PyObject *, void *);
|
||||
|
|
@ -522,7 +637,7 @@ Accessing attributes of extension types
|
|||
It should return a new reference on success or ``NULL`` with a set exception
|
||||
on failure.
|
||||
|
||||
``set`` functions take two :c:type:`PyObject*` parameters (the instance and
|
||||
``set`` functions take two :c:expr:`PyObject*` parameters (the instance and
|
||||
the value to be set) and a function pointer (the associated ``closure``)::
|
||||
|
||||
typedef int (*setter)(PyObject *, PyObject *, void *);
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@ Operating System Utilities
|
|||
|
||||
Return true (nonzero) if the standard I/O file *fp* with name *filename* is
|
||||
deemed interactive. This is the case for files for which ``isatty(fileno(fp))``
|
||||
is true. If the global flag :c:data:`Py_InteractiveFlag` is true, this function
|
||||
is true. If the :c:member:`PyConfig.interactive` is non-zero, this function
|
||||
also returns true if the *filename* pointer is ``NULL`` or if the name is equal to
|
||||
one of the strings ``'<stdin>'`` or ``'???'``.
|
||||
|
||||
This function must not be called before Python is initialized.
|
||||
|
||||
|
||||
.. c:function:: void PyOS_BeforeFork()
|
||||
|
||||
|
|
@ -96,16 +98,16 @@ Operating System Utilities
|
|||
|
||||
Return true when the interpreter runs out of stack space. This is a reliable
|
||||
check, but is only available when :const:`USE_STACKCHECK` is defined (currently
|
||||
on Windows using the Microsoft Visual C++ compiler). :const:`USE_STACKCHECK`
|
||||
will be defined automatically; you should never change the definition in your
|
||||
own code.
|
||||
on certain versions of Windows using the Microsoft Visual C++ compiler).
|
||||
:const:`USE_STACKCHECK` will be defined automatically; you should never
|
||||
change the definition in your own code.
|
||||
|
||||
|
||||
.. c:function:: PyOS_sighandler_t PyOS_getsig(int i)
|
||||
|
||||
Return the current signal handler for signal *i*. This is a thin wrapper around
|
||||
either :c:func:`sigaction` or :c:func:`signal`. Do not call those functions
|
||||
directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:type:`void
|
||||
directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:expr:`void
|
||||
(\*)(int)`.
|
||||
|
||||
|
||||
|
|
@ -114,7 +116,7 @@ Operating System Utilities
|
|||
Set the signal handler for signal *i* to be *h*; return the old signal handler.
|
||||
This is a thin wrapper around either :c:func:`sigaction` or :c:func:`signal`. Do
|
||||
not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef
|
||||
alias for :c:type:`void (\*)(int)`.
|
||||
alias for :c:expr:`void (\*)(int)`.
|
||||
|
||||
.. c:function:: wchar_t* Py_DecodeLocale(const char* arg, size_t *size)
|
||||
|
||||
|
|
@ -165,7 +167,7 @@ Operating System Utilities
|
|||
|
||||
.. versionchanged:: 3.8
|
||||
The function now uses the UTF-8 encoding on Windows if
|
||||
:c:data:`Py_LegacyWindowsFSEncodingFlag` is zero;
|
||||
:c:member:`PyConfig.legacy_windows_fs_encoding` is zero;
|
||||
|
||||
|
||||
.. c:function:: char* Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
|
||||
|
|
@ -177,7 +179,7 @@ Operating System Utilities
|
|||
|
||||
Return a pointer to a newly allocated byte string, use :c:func:`PyMem_Free`
|
||||
to free the memory. Return ``NULL`` on encoding error or memory allocation
|
||||
error
|
||||
error.
|
||||
|
||||
If error_pos is not ``NULL``, ``*error_pos`` is set to ``(size_t)-1`` on
|
||||
success, or set to the index of the invalid character on encoding error.
|
||||
|
|
@ -207,7 +209,7 @@ Operating System Utilities
|
|||
|
||||
.. versionchanged:: 3.8
|
||||
The function now uses the UTF-8 encoding on Windows if
|
||||
:c:data:`Py_LegacyWindowsFSEncodingFlag` is zero;
|
||||
:c:member:`PyConfig.legacy_windows_fs_encoding` is zero.
|
||||
|
||||
|
||||
.. _systemfunctions:
|
||||
|
|
@ -264,10 +266,17 @@ accessible to C code. They all work with the current interpreter thread's
|
|||
|
||||
.. c:function:: void PySys_SetPath(const wchar_t *path)
|
||||
|
||||
This API is kept for backward compatibility: setting
|
||||
:c:member:`PyConfig.module_search_paths` and
|
||||
:c:member:`PyConfig.module_search_paths_set` should be used instead, see
|
||||
:ref:`Python Initialization Configuration <init-config>`.
|
||||
|
||||
Set :data:`sys.path` to a list object of paths found in *path* which should
|
||||
be a list of paths separated with the platform's search path delimiter
|
||||
(``:`` on Unix, ``;`` on Windows).
|
||||
|
||||
.. deprecated:: 3.11
|
||||
|
||||
.. c:function:: void PySys_WriteStdout(const char *format, ...)
|
||||
|
||||
Write the output string described by *format* to :data:`sys.stdout`. No
|
||||
|
|
@ -341,7 +350,7 @@ accessible to C code. They all work with the current interpreter thread's
|
|||
leaks.)
|
||||
|
||||
Note that ``#`` format characters should always be treated as
|
||||
``Py_ssize_t``, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined.
|
||||
:c:type:`Py_ssize_t`, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined.
|
||||
|
||||
:func:`sys.audit` performs the same function from Python code.
|
||||
|
||||
|
|
@ -349,14 +358,14 @@ accessible to C code. They all work with the current interpreter thread's
|
|||
|
||||
.. versionchanged:: 3.8.2
|
||||
|
||||
Require ``Py_ssize_t`` for ``#`` format characters. Previously, an
|
||||
Require :c:type:`Py_ssize_t` for ``#`` format characters. Previously, an
|
||||
unavoidable deprecation warning was raised.
|
||||
|
||||
|
||||
.. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
|
||||
|
||||
Append the callable *hook* to the list of active auditing hooks.
|
||||
Return zero for success
|
||||
Return zero on success
|
||||
and non-zero on failure. If the runtime has been initialized, also set an
|
||||
error on failure. Hooks added through this API are called for all
|
||||
interpreters created by the runtime.
|
||||
|
|
@ -370,7 +379,7 @@ accessible to C code. They all work with the current interpreter thread's
|
|||
silently abort the operation by raising an error subclassed from
|
||||
:class:`Exception` (other errors will not be silenced).
|
||||
|
||||
The hook function is of type :c:type:`int (*)(const char *event, PyObject
|
||||
The hook function is of type :c:expr:`int (*)(const char *event, PyObject
|
||||
*args, void *userData)`, where *args* is guaranteed to be a
|
||||
:c:type:`PyTupleObject`. The hook function is always called with the GIL
|
||||
held by the Python interpreter that raised the event.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue